前言
在我们了解Proxy与Object.defineProperty 的区别之前 先了解一下它们都是怎么定义的。
1.Proxy
可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。
2.Object.defineProperty
Object.defineproperty 其实与Proxy很相似,也可以对目标对象进行拦截操作,它是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。
Proxy
定义一个对象
let obj = {
name: '小明',
address: '郑州',
money: 999999,
}
创建一个Proxy实例对象
let proxy_ = new Proxy(obj, {
//获取拦截
get(target, prokey, self) {
if (prokey == 'money') {
//money被拦截 不可获取到 返回一个认为设置的错误
throw '余额为******';
}
return target[prokey]//返回正常访问的值
},
//修改拦截
set(target, prokey, value) {
if (prokey == 'money') {
throw '我的金库 不可侵入'
} else if (!(prokey in target)) {
throw `${prokey} is not defind`
} else {
target[prokey] = value;
}
},
//查看拦截
has(target, prokey) {
if (prokey == 'data') {
return false
}
return prokey in target
},
//删除拦截
deleteProperty(target, prokey) {
if (prokey == 'money') {
throw '你无权动我的财产';
}
delete target[prokey]
}
});
Object.defineProperty
1.Object.definePropety()定义新属性或修改原有属性
2.Object.definePropety(obj,prop,descriptor)第三个参数 以对象形式{}书写
3. value:设置属性的值 默认为underfined
4.writable:值是否可以重写。 默认为false
5.enumerable:目标属性是否可以被枚举.默认为false
6.configurable:目标属性是否可以被删除或是否可以再次修改特性默认为false
定义一个对象
let obj = {
name: '小明',
address: '郑州',
money: 9887844,
age:18
}
创建一个Object.defineProperty实例对象
Object.defineProperty(obj,'age',{
value:22,//进行拦截返回设置的值
writable:false,//不允许修改
enumerable:false,//不允许被枚举
configurable:true//允许被删除
})
注意:
1.value和 get 是同一个作用,只能同时用一个。
2.writable和set是同一个作用,用一个。
错误代码示范:
Object.defineProperty(obj,'money',{
value:666,
get(){
return 999
}
})
//value和 get 是同一个作用,只能同时用一个 同理set与writable一样
报错:
总结
1.Proxy性能优于Object.defineProperty。 Proxy代理的是整个对象Object.defineProperty只代理对象上的某个属性,如果是多层嵌套的数据需要循环递归绑定;
2.对象上定义新属性时,Proxy可以监听到,Object.defineProperty监听不到,需要借助$set方法;
3.数组的某些方法(push、unshift和splice)Object.defineProperty监听不到,Proxy可以监听到;
4.Proxy在ie浏览器存在兼容性问题