什么是`delete`在JavaScript中非常有用的用例?

时间:2011-08-25 15:51:29

标签: javascript memory-management

我们在这里有一些问题以更抽象的方式讨论删除,但我正在寻找可以使用delete的实际例子,而不是做一些事情,例如将属性设置为null或undefined

The delete operator deletes a property of an object.

遇到某种挑战的情况是什么,delete是最好的解决方案,而不是其他什么?

4 个答案:

答案 0 :(得分:4)

将对象用作hashmap时,可以使用以下方法迭代对象的属性:

for (var key in obj) {
    // ...
}

如果该对象的某些属性设置为null,则其键将包含在那里。使用delete,您可以完全删除其密钥。

答案 1 :(得分: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

in运算符为任何存在的属性返回true,无论它的值是什么。如果您希望它返回false,则需要delete该属性。

在这两种情况下,将其设置为nullundefined都不会执行任何操作(因为它有一个不执行任何操作的setter,或者in运算符的工作方式)

答案 2 :(得分: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)

答案 3 :(得分: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

<强>参考