如何从JavaScript对象中删除属性?

7445

给定一个对象:

let myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

如何删除属性regex以得到以下的myObject

let myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI"
};
38个回答

53

假设您有一个看起来像这样的对象:

var Hogwarts = {
    staff : [
        'Argus Filch',
        'Filius Flitwick',
        'Gilderoy Lockhart',
        'Minerva McGonagall',
        'Poppy Pomfrey',
        ...
    ],
    students : [
        'Hannah Abbott',
        'Katie Bell',
        'Susan Bones',
        'Terry Boot',
        'Lavender Brown',
        ...
    ]
};

删除对象属性

如果你想使用整个staff数组,正确的方式是这样做:

delete Hogwarts.staff;

或者,你也可以这样做:

delete Hogwarts['staff'];

同样地,如果要删除整个学生数组,可以调用 delete Hogwarts.students;delete Hogwarts['students'];

删除数组索引

如果您想删除单个教职员工或学生,则操作有所不同,因为两个属性本身都是数组。

如果您知道员工的索引,可以这样做:

Hogwarts.staff.splice(3, 1);

如果您不知道索引,您还需要进行索引搜索:

Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);

注意

虽然你可以在数组中使用 delete,但这样做会导致稍后调用例如 Hogwarts.staff.length 时获得不正确的结果。换句话说,delete 将删除元素,但它不会更新 length 属性的值。使用 delete 也会破坏你的索引。

因此,在从对象中删除值时,始终首先考虑你是否正在处理对象属性或数组值,并根据此选择适当的策略。

如果想要尝试一下,请使用 这个Fiddle 作为起点。


42

我个人使用Underscore.jsLodash来操作对象和数组:

myObject = _.omit(myObject, 'regex');

39
使用delete方法是实现此目的的最佳方式,根据MDN的描述,delete运算符会从对象中删除属性。因此,您可以简单地编写以下代码:
delete myObject.regex;
// OR
delete myObject['regex'];

删除操作符从对象中删除某个给定的属性。删除成功时,它会返回true,否则将返回false。但是需要考虑以下几种情况:

如果要删除的属性不存在,则delete没有任何效果,并返回true。 如果在对象的原型链上存在同名属性,则在删除后,对象将使用原型链上的属性(换句话说,delete仅对自有属性产生影响)。 使用var声明的任何属性都无法从全局范围或函数作用域中删除。 因此,delete不能删除全局范围内的任何函数(无论这是否是函数定义的一部分还是函数表达式)。 作为对象一部分的函数(除了全局范围)可以使用delete删除。 使用let或const声明的任何属性都无法从定义它们的范围中删除。不可配置的属性无法被删除。这包括Math、Array、Object等内置对象的属性以及使用Object.defineProperty()等方法创建为不可配置的属性。

下面的片段提供了另一个简单的示例:

var Employee = {
  age: 28,
  name: 'Alireza',
  designation: 'developer'
}

console.log(delete Employee.name);   // returns true
console.log(delete Employee.age);    // returns true

// When trying to delete a property that does 
// not exist, true is returned 
console.log(delete Employee.salary); // returns true

了解更多信息并查看更多示例,请访问以下链接:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete


35
有几种方法可以从对象中删除属性:
1)使用点属性访问器进行删除(可变的)

const myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*",
};

delete myObject.regex;
console.log(myObject);

2. 使用方括号属性访问器(可变)进行移除

const myObject = {
      "ircEvent": "PRIVMSG",
      "method": "newURI",
      "regex": "^http://.*",
    };

delete myObject['regex'];
console.log(myObject);
// or
const name = 'ircEvent';
delete myObject[name];
console.log(myObject);

3) 使用对象解构和剩余语法可以在不改变原始对象的情况下进行移除(不可变)

 const myObject = {
      "ircEvent": "PRIVMSG",
      "method": "newURI",
      "regex": "^http://.*",
    };

const { regex, ...myObjectRest} = myObject;
console.log(myObjectRest); 


34

使用Array#reduce方法也可以得到另一种解决方案。

var myObject = {
  "ircEvent": "PRIVMSG",
  "method": "newURI",
  "regex": "^http://.*"
};

myObject = Object.keys(myObject).reduce(function(obj, key) {
  if (key != "regex") {           //key you want to remove
    obj[key] = myObject[key];
  }
  return obj;
}, {});

console.log(myObject);

然而,它将改变原始对象。如果你想创建一个没有指定键的新对象,只需将reduce函数分配给一个新变量,例如:

(ES6)

const myObject = {
  ircEvent: 'PRIVMSG',
  method: 'newURI',
  regex: '^http://.*',
};

const myNewObject = Object.keys(myObject).reduce((obj, key) => {
  key !== 'regex' ? obj[key] = myObject[key] : null;
  return obj;
}, {});

console.log(myNewObject);


29

这里有很多好的答案,但我想补充一点,当使用 JavaScript 中的 delete 来删除属性时,通常最好先检查该属性是否存在以避免错误。

例如:

var obj = {"property":"value", "property2":"value"};

if (obj && obj.hasOwnProperty("property2")) {
  delete obj.property2;
} else {
  //error handling
}
由于 JavaScript 的动态性质,常常存在一些情况你并不确定属性是否存在。在使用 && 运算符之前检查 obj 是否存在还可以确保在未定义的对象上调用 hasOwnProperty() 函数时不会引发错误。
如果这并没有对您的具体用例有所帮助,请谅解,但我认为在管理对象及其属性时,这是一个好的设计可供参考。

26

这篇文章已经很旧了,但我认为它非常有用,所以我决定分享我写的unset函数,以防其他人看到这篇文章并认为为什么它不像PHP unset函数那样简单。

编写这个新的unset函数的原因是要保留此哈希映射中所有其他变量的索引。请看以下示例,并查看从哈希映射中删除值后“test2”的索引未更改的方式。

function unset(unsetKey, unsetArr, resort) {
  var tempArr = unsetArr;
  var unsetArr = {};
  delete tempArr[unsetKey];
  if (resort) {
    j = -1;
  }
  for (i in tempArr) {
    if (typeof(tempArr[i]) !== 'undefined') {
      if (resort) {
        j++;
      } else {
        j = i;
      }
      unsetArr[j] = tempArr[i];
    }
  }
  return unsetArr;
}

var unsetArr = ['test', 'deletedString', 'test2'];

console.log(unset('1', unsetArr, true)); // output Object {0: "test", 1: "test2"}
console.log(unset('1', unsetArr, false)); // output Object {0: "test", 2: "test2"}


20

使用ramda#dissoc,您将获得一个没有regex属性的新对象:

const newObject = R.dissoc('regex', myObject);
// newObject !== myObject

您也可以使用其他函数来达到相同的效果 - 省略、选择等等...


19

尝试以下方法。将Object属性值分配为undefined。然后对对象进行stringifyparse

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));

console.log(myObject);


16

使用 Lodash

import omit from 'lodash/omit';

const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');

使用 Ramda

R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}

你的代码 _.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); 对我来说不起作用,但是 _.omit({a: 1, b: 2, c: 3, d: 4}, ['a', 'd']); 却可以。 - ー PupSoZeyDe ー

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