如何删除Proxy创建的对象的属性?
How to delete a property of the object created by Proxy?
proxy = new Proxy({}, {
deleteProperty(target, propKey){
console.log(arguments);
return true;
}
});
proxy.xx = 3;
delete proxy.xx; // log and return true
proxy.xx // 3
和代码一样,删除操作没有效果。
我在 MDN 上阅读了 delete operator:
The delete operator removes a given property from an object. On successful deletion, it will return true, else false will be returned. However, it is important to consider the following scenarios:
如果您要删除的 属性 不存在,删除将不会有任何效果,并且 return 为真
如果对象的原型链上存在同名的属性,则删除后对象会使用原型链中的属性(在其他也就是说,删除只对自己的属性有影响)。
任何用 var 声明的 属性 不能从全局作用域或函数作用域中删除。
因此,delete 无法删除全局范围内的任何函数(无论这是来自函数定义还是函数表达式的一部分)。
作为对象一部分的函数(除了全局作用域)可以用 delete 删除。
任何用 let 或 const 声明的 属性 不能从它们定义的范围中删除。
无法删除不可配置的属性。这包括 Math、Array、Object 等内置对象的属性,以及使用 Object.defineProperty().
等方法创建为不可配置的属性
我觉得我的代码不属于上面这些,怎么解释呢?谢谢
如果你想删除一个属性,你必须调用Reflect.deleteProperty()
。只是 returning true
不会删除它,它只会调用 Reflect.deleteProperty()
return true
:
const proxy1 = new Proxy({}, {
deleteProperty(target, propKey) {
return true;
},
});
proxy1.xx = 3;
// true, because deleteProperty trap returns true.
console.log(Reflect.deleteProperty(proxy1, 'xx'));
// 3, because it wasn't actually deleted.
console.log(proxy1.xx); // 3
const proxy2 = new Proxy({}, {
deleteProperty(target, propKey) {
Reflect.deleteProperty(target, propKey);
return false;
},
});
proxy2.xx = 3;
// false, because deleteProperty trap returns false.
console.log(Reflect.deleteProperty(proxy2, 'xx'));
// undefined, because it was deleted.
console.log(proxy2.xx);
在 spec 中您可以看到,如果在代理中实现了 deleteProperty 处理程序,那么此处理程序只需调用参数 target
、P
,其中 target
- 是源对象,P
是 属性 删除。
如果您从这个处理程序 true
中 return,就像在您的示例中一样,则不会发生任何其他情况。
因此,如果您添加此处理程序,您应该手动 删除 需要的 属性,或者使用 Reflect
proxy = new Proxy({}, {
deleteProperty(target, propKey) {
console.log(target, propKey);
delete target[propKey];
return true;
}
});
proxy.xx = 3;
console.log('before', proxy.xx);
console.log('delete', delete proxy.xx); // log and return true
console.log('after', proxy.xx); // 3
.as-console-wrapper {
top: 0;
height: 100% !important;
}
proxy = new Proxy({}, {
deleteProperty(target, propKey){
console.log(arguments);
return true;
}
});
proxy.xx = 3;
delete proxy.xx; // log and return true
proxy.xx // 3
和代码一样,删除操作没有效果。
我在 MDN 上阅读了 delete operator:
The delete operator removes a given property from an object. On successful deletion, it will return true, else false will be returned. However, it is important to consider the following scenarios:
如果您要删除的 属性 不存在,删除将不会有任何效果,并且 return 为真
如果对象的原型链上存在同名的属性,则删除后对象会使用原型链中的属性(在其他也就是说,删除只对自己的属性有影响)。
任何用 var 声明的 属性 不能从全局作用域或函数作用域中删除。
因此,delete 无法删除全局范围内的任何函数(无论这是来自函数定义还是函数表达式的一部分)。
作为对象一部分的函数(除了全局作用域)可以用 delete 删除。
任何用 let 或 const 声明的 属性 不能从它们定义的范围中删除。
无法删除不可配置的属性。这包括 Math、Array、Object 等内置对象的属性,以及使用 Object.defineProperty().
等方法创建为不可配置的属性
我觉得我的代码不属于上面这些,怎么解释呢?谢谢
如果你想删除一个属性,你必须调用Reflect.deleteProperty()
。只是 returning true
不会删除它,它只会调用 Reflect.deleteProperty()
return true
:
const proxy1 = new Proxy({}, {
deleteProperty(target, propKey) {
return true;
},
});
proxy1.xx = 3;
// true, because deleteProperty trap returns true.
console.log(Reflect.deleteProperty(proxy1, 'xx'));
// 3, because it wasn't actually deleted.
console.log(proxy1.xx); // 3
const proxy2 = new Proxy({}, {
deleteProperty(target, propKey) {
Reflect.deleteProperty(target, propKey);
return false;
},
});
proxy2.xx = 3;
// false, because deleteProperty trap returns false.
console.log(Reflect.deleteProperty(proxy2, 'xx'));
// undefined, because it was deleted.
console.log(proxy2.xx);
在 spec 中您可以看到,如果在代理中实现了 deleteProperty 处理程序,那么此处理程序只需调用参数 target
、P
,其中 target
- 是源对象,P
是 属性 删除。
如果您从这个处理程序 true
中 return,就像在您的示例中一样,则不会发生任何其他情况。
因此,如果您添加此处理程序,您应该手动 删除 需要的 属性,或者使用 Reflect
proxy = new Proxy({}, {
deleteProperty(target, propKey) {
console.log(target, propKey);
delete target[propKey];
return true;
}
});
proxy.xx = 3;
console.log('before', proxy.xx);
console.log('delete', delete proxy.xx); // log and return true
console.log('after', proxy.xx); // 3
.as-console-wrapper {
top: 0;
height: 100% !important;
}