deleteProperty(target, propKey): 用于拦截delete操作。返回一个布尔值。
该方法主要是拦截delete操作,并在deleteProperty执行真正想做的操作,同时对proxy的属性执行delete操作,若deleteProperty中不设置delete target[ket],则不会真正将该属性删除。 无法删除目标对象自身的不可配置(configurable)的属性,否则报错。
Object.defineProperty():拦截Object.defineProperty(proxy, propKey, propDesc)。 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。详细可参考:Object.defineProperty() - JavaScript | MDN
当Object.defineProperty(obj)时
//deleteProperty(target, propKey)
/*用于拦截delete操作。返回一个布尔值;
该方法主要是拦截delete操作,并在deleteProperty执行真正想做的操作,同时对proxy的属性执行delete操作,若deleteProperty中不设置delete target[ket],则不会真正将该属性删除;
不可以删除目标对象自身的不可配置(configurable)的属性,否则报错。*/
//当Object.defineProperty(obj)时
{
let obj = {
a:1,
b:2
}
Object.defineProperty(obj,'c',{
configurable:true,//这里设置了允许删除该属性
value:'123'
});
let proxy = new Proxy(obj,{
//删除的方法只作用于Proxy对象
deleteProperty(target,key){
//设置为只允许删除 a 属性
if(key === 'a'){
//对于proxy对象,真正删除的是在deleteProperty中执行
delete target[key];
return true;
}else {
return target[key];
}
}
});
delete proxy.a;
delete proxy.b; //对于proxy对象,在deleteProperty()中设置了只允许a属性删除,故这里删除无效
//delete obj.b; 可删除b 因为时直接对obj操作,忽略proxy的限制
console.log(proxy.a); //undefined
console.log(proxy.b); //2
}
当Object.defineProperty(proxy)时
{
let obj={
a:1,
b:2
}
let proxy=new Proxy(obj,{
//删除的方法只作用于Proxy对象
deleteProperty(target,key){
//设置为只允许删除 a 属性
if(key==="a"){
delete target[key];//对于proxy对象,真正删除的是在deleteProperty中执行
return true;
}else{
return target[key];
}
}
})
Object.defineProperty(proxy,"c",{
configurable:true, //这里设置了允许删除该属性
value:"123"
})
delete proxy.c; //proxy规定只能删除 a 属性
console.log('obj',obj); //obj {a: 1, b: 2, c: "123"}
console.log(proxy); //Proxy {a: 1, b: 2, c: "123"}
delete obj.c; //obj没有规定只能删除 a 属性
console.log('obj',obj); //obj {a: 1, b: 2}
console.log(proxy); //Proxy {a: 1, b: 2}
}
结论:通过两个对比 Object.defineProperty(obj)和 Object.defineProperty(proxy), 我们可以看出无论Object.defineProperty()目标对象是哪个,代理对象proxy都直接受到原始对象obj的影响,即在对应属性的 Object.defineProperty中的configurable:true时,proxy设置不可以删除的属性,obj都可以帮它删除,在原始对象上执行delete obj.xx 操作时,可以直接忽略代理对象Proxy中的限制。
参考链接:对proxy的理解及其常见用法