在JavaScript中,`delete`什么时候非常有用?有哪些使用案例?

6

我们这里有一些讨论删除的抽象问题,但我正在寻找实际的例子来说明何时使用delete,而不是像将属性设置为null或undefined。

删除运算符删除对象的属性。

在某个挑战中,什么情况下使用delete是最好的解决方案,而不是其他方法?


阅读完《JavaScript:前20年》https://dl.acm.org/doi/10.1145/3386327 后,我有一种感觉,即删除操作是作为补充目的添加的,因为属性可能是动态添加的,所以它们也应该能够被删除。 - Qiulang
4个回答

4
当使用一个对象作为哈希表时,可以使用以下方法遍历该对象的属性:
for (var key in obj) {
    // ...
}

如果对象的某些属性被设置为null,它们的键将包含在其中。通过使用delete,您可以完全删除它们的键。

2
Object.defineProperty(Object.prototype, "Incognito", {
  get: function() { return 42; },
  set: function() { },
  configurable: true
});

console.log(({}).Incognito); // 42
({}).Incognito = null;
console.log(({}).Incognito); // 42

// I DO NOT WANT INCOGNITO
delete Object.prototype.Incognito
console.log(({}).Incognito); // undefined

如果某个属性有一个空的setter(因为有人认为这是个好主意),如果你想要摆脱它,就需要将其删除。

var hash = {
  "FALSE": undefined,
  "TRUE": null
}

console.log("TRUE" in hash); // true
console.log("FALSE" in hash); // true
delete hash.FALSE;
console.log("FALSE" in hash); // false
< p > in 运算符返回任何存在的属性的 true 值,无论它的值是什么。如果你想要它返回 false,你需要 delete 属性。

在这两种情况下,将其设置为 nullundefined 都不起作用(因为它要么有一个什么都不做的 setter,要么就是 in 运算符的工作方式)


我不明白。那有什么意义呢?问题涉及应用逻辑(就我所知)。因此,问题仍然存在,使用delete而不是将变量/属性设置为null的好处是什么。 - jAndy
1
@jAndy 抱歉,我的意思是将其置空并不起作用。我已经稍微更清楚地表达了。 - Raynos
嗯,这个回答来得有点晚了。第一个版本(只有.defineProperty)没有太多意义。 - jAndy
@jAndy 我有点希望你自己扩展填充点。 - Raynos
没有办法在第一个版本中实现那个功能。不过现在没问题了 ;) - jAndy

1
将对象的属性设置为 nullundefined 仍会使该属性可枚举 - 如果你在任何阶段对对象进行 for...in 遍历,并且存在属性是重要的,那么这就是你想使用 delete 的时候。
例如,如果你有一个构造函数,它以对象作为参数,继承自另一个做同样操作的构造函数,当调用父级构造函数时属性的存在是很重要的(比如,在下面的示例中,ParentWidgets 使用它的参数与 for...in 一起生成 HTML 属性),你将需要使用 delete 删除不相关的属性:
function ChildWidget(kwargs) {
  kwargs = extend({
    childSpecific1: null, childSpecific2: 42
  }, kwargs || {})
  this.childSpecific1 = kwargs.childSpecific1
  this.childSpecific2 = kwargs.childSpecific2
  delete kwargs.childSpecific1
  delete kwargs.childSpecific2
  ParentWidget.call(this, kwargs)
}
inherits(ChildWidget, ParentWidget)

0

delete操作符在重置或清除方法中非常有用,可以删除与表单相关的对象字面数据:

delete formmap["forms"]

它还可以用于删除与状态相关联的对象:

/* lights... */
if (node["alpha"+i].active)
  {
  // camera, action
  node["beta"+i] = chi;
  }
else
  {
  /* cut! */
  delete node["beta"+i];
  node["omega"].state = false;
  }

此外,它还可以作为内联可选对象属性的简写形式,非常有用:
var foo = {"bar": [], "drink": [], "tab": [] }

// happy hour
this.bar && (foo["bar"]).push(this.bar) || delete foo.bar;
// open a tab
this.drink && (foo["drink"]).push(this.drink) || delete foo.drink;
// cheers
this.tab && (foo["tab"]).push(this.tab) || delete foo.tab;

最后,通过使用类型特定实例属性的可写权限作为试金石,它是一种区分类型的有用方式:

// Function
!!foo.prototype === true && delete foo.length === false && delete foo[-1] === true

// Object, Number, Infinity, or Boolean (probably Object)
!!foo.prototype === false && delete foo.length === true && delete foo[-1] === true

// Array
!!foo.prototype === false && delete foo.length === false && delete foo[-1] === true

// String
!!foo.prototype === false && delete foo.length === false && delete foo[-1] === false

// RegExp
delete foo.source === false

参考资料


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接