众所周知 vue2所使用的双向绑定原理是用了Object.defineProperty 来进行数据的拦截处理,而vue3使用了es6的 proxy代理拦截数据。
相比较proxy,Object.defineProperty有哪些区别或者说是缺点呢?
- 在vue里,Object.defineProperty无法监听到数组的下标的变化,也就是说直接根据数组索引添加值Object.defineProperty是无法监听到修改的;(Object.defineProperty其实应该是可以监听到的,但是尤大觉得在数组数据比较多的时候去拿索引修改值非常损耗性能,所以屏蔽了这个功能)
- object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,所以值还是对象的话还需深度遍历;而proxy可以监听整个对象;
- proxy不仅可以代理对象还可以代理数组,能代理动态新增的属性;
回到正文来,那么 proxy是啥呢?
菜鸟教程 ES6 Reflect 与 Proxy
proxy小试牛刀
先声明一个变量
const obj = {
name: 'dingzong'
};
创建一个proxy实例
const _obj = new Proxy(obj, {})
输出_obj
构造函数proxy第二项是一个对象,对象里有内置十三种方法来捕获数据;
这里查看proxy第二项里对象的方法
get set方法浅试
const _obj = new Proxy(obj, {
get: function(target, key) {
console.log(`当前对象的key是 ${key},输出${target[key]}`);
return target[key]
},
set: function(target, key, val) {
console.log(`当前对象的key是 ${key}, 新值是${val}`);
target[key] = val
}
})
输出_obj.name时会触发get方法,
重新赋值_obj.name时触发set方法;
可以在这些方法里进行对应的操作。
当然上面的案例用Object.defineProperty也可以简单的实现,但是Object.defineProperty的设计初衷并不是为了去监听拦截一个对象中的属性(且效率也不高),且他也实现不了更加丰富的操作。