【问题标题】:What are some use-cases of when `delete` has been very useful in JavaScript?当 `delete` 在 JavaScript 中非常有用时,有哪些用例?
【发布时间】:2011-11-03 20:06:49
【问题描述】:

我们在这里有一些问题以更抽象的方式讨论删除,但我正在寻找可以使用 delete 的实际示例,而不是执行诸如将属性设置为 null 或 undefined 之类的操作。

The delete operator deletes a property of an object.

什么是某处面临挑战的情况,delete 是最好的解决方案,而不是其他的?

【问题讨论】:

  • 看完《JavaScript:前 20 年》dl.acm.org/doi/10.1145/3386327 感觉delete是作为补充的,因为属性可能是动态添加的,所以应该也可以删除。

标签: javascript memory-management


【解决方案1】:

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

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
    

    如果您想摆脱它,则需要删除任何具有空设置器的属性(因为有人认为 是个好主意)。

    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 运算符的工作方式)

    【讨论】:

    • 我不明白。有什么意义?问题与应用程序逻辑有关(据我所知)。所以问题仍然悬而未决,使用delete 而不仅仅是null 变量/属性有什么好处。
    • @jAndy 抱歉,将其归零是行不通的。我已经说得更清楚了。
    • 呃,这个答案很晚才出现。第一个版本(只是.defineProperty)没有多大意义。
    • @jAndy 我有点希望你自己扩展填充点。
    • 没有办法在第一个版本上得到它。不过,现在很好;)
    【解决方案3】:

    将对象的属性设置为 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)
    

    【讨论】:

      【解决方案4】:

      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
      

      参考文献

      【讨论】:

        猜你喜欢
        • 2015-07-16
        • 2017-02-13
        • 1970-01-01
        • 2020-10-03
        • 2011-08-31
        • 1970-01-01
        • 2011-02-07
        • 2011-05-04
        • 2011-12-23
        相关资源
        最近更新 更多