1
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 上阅读了删除运算符:

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

  • 如果您尝试删除的属性不存在,则 delete 不会产生任何效果并返回 true

  • 如果对象的原型链上存在同名的属性,那么在删除后,对象将使用原型链中的属性(也就是说,删除只对自己的属性有影响)。

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

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

    • 作为对象一部分的函数(除了全局范围)可以用 delete 删除。

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

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

我想我的代码不属于上面这些,那怎么解释呢?谢谢。

4

2 回答 2

3

如果你想删除一个属性,你必须调用Reflect.deleteProperty(). 只是返回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);

于 2016-11-17T13:06:07.287 回答
1

规范中你可以看到,如果在代理中实现了deleteProperty处理程序,那么这个处理程序只需使用参数调用targetP其中target- 是源对象,并且P是要删除的属性。

如果您从这个处理程序返回true,就像在您的示例中一样,则不会发生任何其他事情。

因此,如果您添加此处理程序,您应该手动删除所需的属性,或者使用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;
}

于 2016-11-17T13:11:24.643 回答