如何删除Proxy创建的对象的属性?

时间:2016-11-17 12:57:30

标签: javascript ecmascript-6 es6-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

  

delete运算符从对象中删除给定属性。成功删除后,它将返回true,否则返回false。但是,考虑以下情况非常重要:

  • 如果您要删除的媒体资源不存在,则删除不会产生任何影响并返回true

  • 如果对象的原型链上存在具有相同名称的属性,则删除后,该对象将使用原型链中的属性(换句话说,删除仅对原型链有影响)自己的财产)。

  • 使用var声明的任何属性都不能从全局范围或函数范围中删除。

    • 因此,删除不能删除全局范围内的任何函数(无论这是函数定义还是函数表达式的一部分)。

    • 可以删除作为对象一部分的功能(除全局范围外)。

  • 使用let或const声明的任何属性都不能从定义它们的作用域中删除。

  • 无法删除不可配置的属性。这包括内置对象的属性,如Math,Array,Object和属性,这些属性是使用Object.defineProperty()等方法创建的。

我认为我的代码不属于上述代码,那么如何解释呢?感谢。

2 个答案:

答案 0 :(得分:2)

如果要删除媒体资源,则必须致电Reflect.deleteProperty()。只是返回true并不会将其删除,只会调用Reflect.deleteProperty()来返回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);




答案 1 :(得分:1)

spec中,您可以看到,如果在代理中实现了 deleteProperty 处理程序,那么此处理程序只需调用参数targetP,其中{{1 - 是源对象,target是要删除的属性。

如果你从这个处理程序P返回,就像你的样本一样,没有其他事情发生。

因此,如果您添加此处理程序,则应手动删除所需属性,或者使用 Reflect

进行近似回答

true
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