【问题标题】:Delete multiple object properties?删除多个对象属性?
【发布时间】:2014-09-11 22:18:54
【问题描述】:

我创建了一个具有多个属性的对象 -

var objOpts = {
  option1: 'Option1',
  option2: 'Option2',
  option2: 'Option3'
};

我稍后会添加更多属性 -

objOpts.option4 = 'Option4'
objOpts.option5 = 'Option5'

我已经完成了后两个创建的属性('Option4' 和 'Option5'),我想清除/删除这两个属性。

目前我会这样做 -

delete objOpts.option4
delete objOpts.option5

还有其他方法可以做到这一点吗?想象一下,我又添加了 5 个属性并需要清除/删除它们,这将是五行几乎相同的“删除”代码

【问题讨论】:

  • var extraOpts = ['option4','option5','option6','option7','option8']; for(index in extraOpts){ delete objOpts[extraOpts[index]]; }
  • 更好...var extraOpts = {}; extraOpts.options = ['option4','option5','option6','option7','option8']; delete extraOpts.options; console.log(extraOpts.options);

标签: javascript oop object


【解决方案1】:

ES6 对此提供了一个优雅的解决方案:Rest in Object Destructuring

let { a, b, ...rest } = { a: 10, b: 20, c: 30, d: 40 };
console.log(rest); // { c: 30, d: 40 }

请注意,这不会改变原始对象,但有些人可能仍然觉得这很有用。

参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

【讨论】:

  • 非常简洁的答案。一个小缺点是 eslist 警告说 a & b 已分配但从未使用过
  • @AharonOhayon eslint.org/docs/rules/no-unused-vars#ignorerestsiblings 可以用来解决这个问题
  • 如果你将解构的 obj 声明为 const 不会删除 elist 警告吗?
  • 带有ESlint 的项目 - 可能会抱怨未使用的变量,因此您可能希望在该特定行之前禁用该规则
  • 一些 linting 规则允许您使用下划线表示未使用的变量,例如:_var,同时仍然允许您像这样声明它:const { _a, _b, ...rest }。否则,您可以将其添加到您的 eslintrc: "no-unused-vars": ["error", { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" }] 以忽略以下划线开头的未使用变量或参数。我真的很喜欢“简洁”的答案,但与大多数简洁的代码一样,它可能不容易理解。不过,您始终可以将其包装在命名函数中以获得更好的可读性。
【解决方案2】:

使用库 lodash 有一个简单的修复方法。

_.omit 函数获取您的对象和要删除的键数组,并返回一个新对象,该对象具有原始对象的所有属性,但数组中提到的属性除外。

这是一种删除键的巧妙方法,因为使用它可以获得一个新对象,而原始对象保持不变。这避免了突变问题,如果我们删除原始对象中的键,则使用该对象的所有其他代码部分可能会破坏或引入代码中的错误。

例子

var obj = {x:1, y:2, z:3};
var result = _.omit(obj, ['x','y']);
console.log(result);

//Output
result = {z:3};

Click Here的文档链接

【讨论】:

    【解决方案3】:

    我确定您正在尝试向对象添加自定义属性。

    我建议的一种更简单的方法是创建一个子属性:

    objOpts.custom.option4 = 'Option4'
    objOpts.custom.option5 = 'Option5'
    

    这样你就可以delete objOpts.custom 完成它。请注意,在此步骤之后,您必须重新创建 objOpts.custom = {}

    此外,这种方式也更接近 OOP,因为您的公共属性很容易与私有属性区分开来。

    如果您刚开始在 JavaScript 中删除对象,我想指出一篇关于该主题的出色文章:http://perfectionkills.com/understanding-delete/

    您可以使用元属性来保护属性不被删除等(为您的案例创建更好的编码流程)

    编辑:

    我想补充一点,而不是删除和重新创建属性,您可以简单地说 objOpts.custom = {},这会从内存中释放 option4option5(最终通过垃圾收集)。

    【讨论】:

      【解决方案4】:

      一种方法是创建一个单独的函数,将您的对象和属性作为参数。

      Js fiddle example

      代码如下:

      var objOpts = {
        option1: 'Option1',
        option2: 'Option2',
        option3: 'Option3',
        option4: 'Option4'
      };
      
      /** 
       * Method for removing object properties
       *
       */
      var removeObjectProperties = function(obj, props) {
      
          for(var i = 0; i < props.length; i++) {
              if(obj.hasOwnProperty(props[i])) {
                  delete obj[props[i]];
              }
          }
      
      };
      
      // remove
      removeObjectProperties(objOpts, ["option1", "option2"]);
      
      // objOpts - after
      console.log(objOpts);
      

      【讨论】:

      • 不需要检查obj.hasOwnProperty(props[i]),因为delete 不需要该属性存在。
      【解决方案5】:

      我还会提供比 Mauno Vänä 更现代的方法:

      function deleteProps (obj, prop) {
          for (const p of prop) {
              (p in obj) && (delete obj[p]);
          }    
      }
      

      例子:

      // Create sample object
      const myObject = {
          a: 'Foo',
          b: 'Baa',
          c: 'Oof'
      };
      
      // Prints: {a: "Foo", b: "Baa", c: "Oof"}
      console.log(myObject);
      
      // Delete props
      deleteProps(myObject, ['a', 'b']);
      
      // Prints: {c: "Oof"}
      console.log(myObject);
      

      【讨论】:

      • 不需要检查(p in obj),因为delete 不需要该属性存在。
      【解决方案6】:
      var obj = {"key1":1,"key2":2,"key3":3,"key4":4};
      
      if (!('multidelete' in Object.prototype)) {
      Object.defineProperty(Object.prototype, 'multidelete', {
          value: function () {
              for (var i = 0; i < arguments.length; i++) {
                  delete this[arguments[i]];
              }
          }
      });
      }
      
      obj.multidelete("key1","key3");
      

      您可以像这样使用它来删除对象中的多个键

      【讨论】:

        【解决方案7】:

        另一种选择是使用Object.assign 将属性设置为nullundefined,具体取决于您的用例。这不会删除属性,但会清除它们。所以你会做这些:

        // Modify the object directly
        Object.assign(objOpts, {option4: null, option5: null});
        

        // Create a copy of the object with the properties cleared 
        const newObject = Object.assign({}, objOpts, {option4: null, option5: null});
        

        您还可以使用数组列出要使用Array.reduce() 清除的属性,以创建Object.assign() 的最后一个参数。

        【讨论】:

          【解决方案8】:
          Object.keys(object).forEach((prop) => delete object[prop]);
          

          【讨论】:

          • 这与delete object 有何不同?
          • 您不能在对象上调用deletedelete 可用于删除对象的属性,而不是对象本身。
          • 这如何允许删除特定属性而不是所有属性?
          • 这似乎是如何删除对象的所有属性的解决方案,留下object === {}。这绝不会回答 OP 的问题。
          【解决方案9】:
          var extraOpts = {}
          extraOpts.options = ['option4','option5','option6','option7','option8']
          delete extraOpts.options
          console.log(extraOpts.options)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-02-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多