存在的问题
在Vue2.0 中,数据双向绑定就是通过Object.defineProperty 去监听对象的每一个属性,然后在get ,set 方法中通过发布订阅者模式来实现的数据响应,但是存在一定的缺陷,比如只能监听已存在的属性,对于新增删除属性就无能为力了,同时无法监听数组的变化,所以在Vue3.0 中将其换成了功能更强大的Proxy 。
请分别使用Object.defineProperty 和Proxy 完善下面的代码逻辑
function observe(obj, callback) {}
const obj = observe(
{
name: '小鱼',
sex: '女'
},
(key, value) => {
console.log(`属性[${key}]的值被修改为[${value}]`)
}
)
obj.name = '小鱿鱼'
obj.sex = '未知'
- 用
Object.defineProperty 实现
function observe(obj, callback) {
const newObj = {}
Object.keys(obj).forEach(key => {
Object.defineProperty(newObj, key, {
configurable: true,
enumerable: true,
get() {
return obj[key]
},
set(newVal) {
obj[key] = newVal
callback(key, newVal)
}
})
})
return newObj
}
const obj = observe(
{
name: '小鱼',
sex: '女'
},
(key, value) => {
console.log(`属性[${key}]的值被修改为[${value}]`)
}
)
obj.name = '小鱿鱼'
obj.sex = '未知'
- 用
Proxy
function observe(obj, callback) {
return new Proxy(obj, {
get(target, key) {
return target[key]
},
set(target, key, value) {
target[key] = value
callback(key, value)
}
})
}
const obj = observe(
{
name: '小鱼',
sex: '女'
},
(key, value) => {
console.log(`属性[${key}]的值被修改为[${value}]`)
}
)
obj.name = '小鱿鱼'
obj.sex = '未知'
从上面可以大概的了解到Object.defineProperty 和Proxy 的用法,但是当给对象添加新的属性的时候,区别就出来了
obj.gzh = '前端有的玩'
使用Object.defineProperty 无法监听到新增属性,但是使用Proxy 是可以监听到的。
proxy
proxy 的意思是 代理,用来代理某些操作。
在访问目标对象之前架设一层拦截机制,外界访问这个对象,都必须通过这个拦截。 因此可以通过这一层拦截机制对这个对象进行过滤和改写。
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。
var proxy = new Proxy(target, handler);
target : 为所要代理的目标对象(target 为一个对象) handler :对代理对象的拦截时进行的操作(handler 中包含方法)
如果handler 没有设置任何拦截,那就等同于直接通向原对象。
var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a
handler 里面的方法有十三个,具体可以参考https://es6.ruanyifeng.com/#docs/proxy
|