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

给定一个对象:

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

如何删除属性regex以获得以下myObject

let myObject = {"ircEvent": "PRIVMSG","method": "newURI"};
2937865 次浏览

要从对象中删除属性(改变对象),您可以这样做:

delete myObject.regex;// or,delete myObject['regex'];// or,var prop = "regex";delete myObject[prop];

演示

var myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*"};delete myObject.regex;
console.log(myObject);

对于任何有兴趣阅读更多信息的人,Stack Overflow用户kangax在他们的博客理解删除上写了一篇关于delete语句的非常深入的博客文章。强烈推荐。

如果您想要一个新的对象,其中包含除一些之外的所有原始键,您可以使用解构

演示

let myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*"};
// assign the key regex to the variable _ indicating it will be unusedconst {regex: _, ...newObj} = myObject;
console.log(newObj);   // has no 'regex' keyconsole.log(myObject); // remains unchanged

var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};    
delete myObject.regex;
console.log ( myObject.regex); // logs: undefined

这适用于Firefox和Internet Explorer,我认为它适用于所有其他版本。

delete运算符用于从对象中删除属性。

const obj = { foo: "bar" };
delete obj.foo;obj.hasOwnProperty("foo"); // false

请注意,对于数组,这与删除一个元素不同。要从数组中删除元素,请使用Array#spliceArray#pop。例如:

arr;             // [0, 1, 2, 3, 4]arr.splice(3,1); // 3arr;             // [0, 1, 2, 4]

详情

严格来说,在JavaScript中不可能真正删除任何东西。delete运算符既不删除对象也不释放内存。相反,它将其操作数设置为undefined并操作父对象,以便成员消失。

let parent = {member: { str: "Hello" }};let secondref = parent.member;
delete parent.member;parent.member;        // undefinedsecondref;            // { str: "Hello" }

对象未删除。只有引用被删除。内存仅被释放当删除对对象的所有引用时,垃圾收集器。

另一个重要的警告是delete运算符不会为您重组结构,这会产生看起来违反直觉的结果。例如,删除数组索引会在其中留下一个“洞”。

let array = [0, 1, 2, 3]; // [0, 1, 2, 3]delete array[2];          // [0, 1, empty, 3]

这是因为数组对象。所以索引与键相同。

let fauxarray = {0: 1, 1: 2, length: 2};fauxarray.__proto__ = [].__proto__;fauxarray.push(3);fauxarray;                // [1, 2, 3]Array.isArray(fauxarray); // falseArray.isArray([1, 2, 3]); // true

JavaScript中的不同内置函数以不同的方式处理带有漏洞的数组。

  • for..in语句将完全跳过空索引。

  • 简单的for循环将为索引处的值产生undefined

  • 任何使用Symbol.iterator的方法都会为索引处的值返回undefined

  • forEachmapreduce将简单地跳过缺少的索引,但不会移除它

示例:

let array = [1, 2, 3]; // [1,2,3]delete array[1];       // [1, empty, 3]array.map(x => 0);     // [0, empty, 0]

因此,delete运算符不应该用于从数组中删除元素的常见用例。数组有专门的方法来删除元素和重新分配内存:Array#splice()Array#pop

数组#拼接(start[, deleteCount[, item1[, item2[,…]]]])

Array#splice改变数组,并返回任何删除的索引。deleteCount元素从索引start中删除,item1, item2... itemN从索引start中插入数组。如果省略deleteCount,则从start Index中删除元素到数组末尾。

let a = [0,1,2,3,4]a.splice(2,2) // returns the removed elements [2,3]// ...and `a` is now [0,1,4]

Array.prototypeArray#slice上还有一个类似命名但不同的函数。

数组#切片([开始[,结束]])

Array#slice是非破坏性的,并返回一个包含从startend的指示索引的新数组。如果end未指定,它默认为数组的末尾。如果end为正,它指定从零开始的非包容性索引以停止。如果end为负,它通过从数组末尾向后计数来指定要停止的索引(例如-1将省略最终索引)。如果end <= start,结果是一个空数组。

let a = [0,1,2,3,4]let slices = [a.slice(0,2),a.slice(2,2),a.slice(2,3),a.slice(2,5) ]
//   a           [0,1,2,3,4]//   slices[0]   [0 1]- - -//   slices[1]    - - - - -//   slices[2]    - -[3]- -//   slices[3]    - -[2 4 5]

数组#pop

Array#pop从数组中删除最后一个元素并返回该元素。此操作更改数组的长度。相反的操作是push

数组#Shift

Array#shift类似于pop,只是它删除了第一个元素。相反的操作是unshift

你在问题标题中使用的术语从JavaScript对象中删除属性可以有不同的解释。一种是将其从整个内存和对象键列表中删除,另一种是将其从对象中删除。正如在其他一些答案中提到的那样,delete关键字是主要部分。假设你的对象像:

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

如果您这样做:

console.log(Object.keys(myJSONObject));

其结果将是:

["ircEvent", "method", "regex"]

您可以从对象键中删除该特定键,例如:

delete myJSONObject["regex"];

那么使用Object.keys(myJSONObject)的对象键将是:

["ircEvent", "method"]

但关键是如果你关心内存并且你想从内存中删除整个对象,建议在删除键之前将其设置为null:

myJSONObject["regex"] = null;delete myJSONObject["regex"];

这里的另一个要点是要小心对同一对象的其他引用。例如,如果您创建了一个变量,如:

var regex = myJSONObject["regex"];

或者将其作为指向另一个对象的新指针添加,例如:

var myOtherObject = {};myOtherObject["regex"] = myJSONObject["regex"];

那么即使你从对象myJSONObject中删除它,该特定对象也不会从内存中删除,因为regex变量和myOtherObject["regex"]仍然有它们的值。那我们怎么能确定地从内存中删除对象呢?

答案是删除代码中所有指向该对象的引用不使用#0语句创建对该对象的新引用。关于var语句的最后一点,是我们通常面临的最关键的问题之一,因为使用var语句会阻止创建的对象被删除。

这意味着在这种情况下,您将无法删除该对象,因为您通过var语句创建了regex变量,如果您这样做:

delete regex; //False

结果将是false,这意味着你的删除语句没有像你预期的那样执行。但是,如果你之前没有创建该变量,并且只有myOtherObject["regex"]作为最后一个现有引用,你可以像这样删除它:

myOtherObject["regex"] = null;delete myOtherObject["regex"];

换句话说,只要您的代码中没有指向该对象的引用,JavaScript对象就有资格被杀死。


更新时间:

感谢@AgentME:

在删除属性之前将其设置为null无法完成任何东西(除非该物体已被Object.seal和删除失败。通常情况并非如此,除非您特别尝试)。

获取更多关于Object.sealObject.seal()的信息

JavaScript中的对象可以被认为是键和值之间的映射。delete运算符用于一次删除这些键,更常见的是对象属性。

var obj = {myProperty: 1}console.log(obj.hasOwnProperty('myProperty')) // truedelete obj.myPropertyconsole.log(obj.hasOwnProperty('myProperty')) // false

delete运算符不直接释放内存,它不同于简单地将nullundefined的值分配给属性,因为属性本身是从对象中删除的。请注意,如果已删除属性的是引用类型(对象),并且您的程序的另一部分仍然保存对该对象的引用,那么该对象当然不会被垃圾收集,直到对它的所有引用都消失。

delete仅适用于描述符将其标记为可配置的属性。

另一种选择是使用Underscore.js库。

请注意,_.pick()_.omit()都返回对象的副本,并且不直接修改原始对象。将结果分配给原始对象应该会起作用(未显示)。

参考:链接_选择(对象,*键)

返回对象的副本,过滤后仅包含对象的值白名单密钥(或有效密钥数组)。

var myJSONObject ={"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.pick(myJSONObject, "ircEvent", "method");=> {"ircEvent": "PRIVMSG", "method": "newURI"};

参考:链接_. omit(对象,*键)

返回对象的副本,过滤后省略将键(或键数组)列入黑名单。

var myJSONObject ={"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.omit(myJSONObject, "regex");=> {"ircEvent": "PRIVMSG", "method": "newURI"};

对于数组,可以以类似的方式使用_.filter()_.reject()

这里有很多很好的答案,但我只是想插一句,当使用删除删除JavaScript中的属性时,首先检查该属性是否存在以防止错误通常是明智的。

e. g

var obj = {"property":"value", "property2":"value"};
if (obj && obj.hasOwnProperty("property2")) {delete obj.property2;} else {//error handling}

由于JavaScript的动态特性,经常会出现你根本不知道属性是否存在的情况。在&&之前检查obj是否存在也可以确保你不会因为调用未定义对象的hasOwnProperty()函数而抛出错误。

很抱歉,如果这没有增加您的特定用例,但我相信这是一个很好的设计,可以在管理对象及其属性时进行调整。

这篇文章非常古老,我发现它非常有帮助,所以我决定分享我写的unset函数,以防其他人看到这篇文章并思考为什么它不像PHP unset函数那么简单。

编写这个新的unset函数的原因是将所有其他变量的索引保留在这个hash_map中。看看下面的例子,看看“test2”的索引在从hash_map中删除一个值后是如何保持不变的。

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"}

ECMAScript 2015(或ES6)带有内置的反映对象。可以通过使用目标对象和属性键作为参数调用Reflect.delete属性()函数来删除对象属性:

Reflect.deleteProperty(myJSONObject, 'regex');

这相当于:

delete myJSONObject['regex'];

但是如果对象的属性不可配置,则不能使用deleteProperty函数或删除运算符删除它:

let obj = Object.freeze({ prop: "value" });let success = Reflect.deleteProperty(obj, "prop");console.log(success); // falseconsole.log(obj.prop); // value

Object.freeze()使得对象的所有属性都不可配置(除了其他东西)。deleteProperty函数(以及删除操作符)在尝试删除它的任何属性时返回false。如果属性是可配置的,即使属性不存在,它也返回true

deletedeleteProperty的区别在于使用严格模式时:

"use strict";
let obj = Object.freeze({ prop: "value" });Reflect.deleteProperty(obj, "prop"); // falsedelete obj["prop"];// TypeError: property "prop" is non-configurable and can't be deleted

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

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

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

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还会搞乱您的索引。

因此,从对象中删除值时,始终首先考虑您是在处理对象属性还是在处理数组值,并在此基础上选择适当的策略。

如果你想尝试这个,你可以使用这个小提琴作为起点。

如果您想删除深度嵌套在对象中的属性,那么您可以使用以下递归函数,并将属性的路径作为第二个参数:

var deepObjectRemove = function(obj, path_to_key){if(path_to_key.length === 1){delete obj[path_to_key[0]];return true;}else{if(obj[path_to_key[0]])return deepObjectRemove(obj[path_to_key[0]], path_to_key.slice(1));elsereturn false;}};

示例:

var a = {level1:{level2:{level3: {level4: "yolo"}}}};
deepObjectRemove(a, ["level1", "level2", "level3"]);console.log(a);
//Prints {level1: {level2: {}}}

尝试以下方法。将Object属性值分配给undefined。然后stringify对象和parse

 var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
myObject.regex = undefined;myObject = JSON.parse(JSON.stringify(myObject));
console.log(myObject);

老问题,现代答案。使用对象解构,一个ECMAScript 6功能,就像这样简单:

const { a, ...rest } = { a: 1, b: 2, c: 3 };

或者用问题示例:

const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};const { regex, ...newObject } = myObject;console.log(newObject);

您可以在Babel试用编辑器中看到它的实际操作。


编辑:

要重新分配给同一个变量,请使用let

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

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

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

您还可以使用其他函数来实现相同的效果-省略,选择,…

另一种解决方案,使用#0

var myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*"};
myObject = Object.keys(myObject).reduce(function(obj, key) {if (key != "regex") {           //key you want to removeobj[key] = myObject[key];}return obj;}, {});
console.log(myObject);

但是,它将突变原始对象。如果您想在指定的键上创建一个新对象没有,只需将duce函数分配给一个新变量,例如:

(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);

使用删除方法是最好的方法,根据MDN描述,删除运算符从对象中删除属性。所以你可以简单地写:

delete myObject.regex;// ORdelete myObject['regex'];

删除运算符从对象中删除给定的属性。在如果删除成功,则返回true,否则返回false。但是,重要的是要考虑以下情况:

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

下面的代码片段给出了另一个简单的示例:

var Employee = {age: 28,name: 'Alireza',designation: 'developer'}
console.log(delete Employee.name);   // returns trueconsole.log(delete Employee.age);    // returns true
// When trying to delete a property that does// not exist, true is returnedconsole.log(delete Employee.salary); // returns true

有关更多信息和查看更多示例,请访问下面的链接:

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

丹的断言表示“删除”非常慢,他发布的基准测试受到质疑。所以我在Chrome59自己进行了测试。似乎“删除”慢了大约30倍:

var iterationsTotal = 10000000;  // 10 millionvar o;var t1 = Date.now(),t2;for (let i=0; i<iterationsTotal; i++) {o = {a:1,b:2,c:3,d:4,e:5};delete o.a; delete o.b; delete o.c; delete o.d; delete o.e;}console.log ((t2=Date.now())-t1);  // 6135for (let i=0; i<iterationsTotal; i++) {o = {a:1,b:2,c:3,d:4,e:5};o.a = o.b = o.c = o.d = o.e = undefined;}console.log (Date.now()-t2);  // 205

请注意,我故意在一个循环周期中执行多个“删除”操作,以尽量减少其他操作造成的影响。

Lodash

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

使用Ramda

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

Object.assign()&Object.keys()&Array.map()

const obj = {"Filters":[{"FilterType":"between","Field":"BasicInformationRow.A0","MaxValue":"2017-10-01","MinValue":"2017-09-01","Value":"Filters value"}]};
let new_obj1 = Object.assign({}, obj.Filters[0]);let new_obj2 = Object.assign({}, obj.Filters[0]);
/*
// old version
let shaped_obj1 = Object.keys(new_obj1).map((key, index) => {switch (key) {case "MaxValue":delete new_obj1["MaxValue"];break;case "MinValue":delete new_obj1["MinValue"];break;}return new_obj1;})[0];

let shaped_obj2 = Object.keys(new_obj2).map((key, index) => {if(key === "Value"){delete new_obj2["Value"];}return new_obj2;})[0];

*/

// new version!
let shaped_obj1 = Object.keys(new_obj1).forEach((key, index) => {switch (key) {case "MaxValue":delete new_obj1["MaxValue"];break;case "MinValue":delete new_obj1["MinValue"];break;default:break;}});
let shaped_obj2 = Object.keys(new_obj2).forEach((key, index) => {if(key === "Value"){delete new_obj2["Value"];}});

我也使用Lodash"unset"来实现嵌套对象……只是这需要编写小逻辑来获取省略方法期望的属性键的路径。

  1. 将属性路径作为数组返回的方法

var a = {"bool":{"must":[{"range":{"price_index.final_price":{"gt":"450", "lt":"500"}}}, {"bool":{"should":[{"term":{"color_value.keyword":"Black"}}]}}]}};
function getPathOfKey(object,key,currentPath, t){var currentPath = currentPath || [];
for(var i in object){if(i == key){t = currentPath;}else if(typeof object[i] == "object"){currentPath.push(i)return getPathOfKey(object[i], key,currentPath)}}t.push(key);return t;}document.getElementById("output").innerHTML =JSON.stringify(getPathOfKey(a,"price_index.final_price"))
<div id="output">
</div>

  1. 然后只需使用Lodash未设置方法从对象中删除属性。

var unset = require('lodash.unset');unset(a, getPathOfKey(a, "price_index.final_price"));

JavaScript中的属性删除

这个页面上有许多不同的选项,不是因为大多数选项都是错误的——或者因为答案是重复的——而是因为适当的技术取决于你所处的情况以及你和/或你的团队试图完成的任务的目标。要明确地回答你的问题,你需要知道:

  1. 您要定位的ECMAScript版本
  2. 您要删除属性的对象类型范围以及您需要能够省略的属性名称类型(仅限字符串?符号?从任意对象映射的弱引用?多年来,这些都是JavaScript中的属性指针类型)
  3. 你和你的团队使用的编程精神/模式。你是喜欢函数式方法,而突变在你的团队中是被禁止的,还是使用狂野的西部突变面向对象技术?
  4. 您是否希望在纯JavaScript中实现这一目标,或者您是否愿意并能够使用第三方库?

一旦回答了这四个查询,JavaScript中基本上有四类“属性删除”可供选择以实现您的目标。它们是:

突变对象属性删除,不安全

此类别适用于当您想保留/继续使用原始引用并且在代码中不使用无状态函数原则时对对象文字或对象实例进行操作。此类别中的一个语法示例:

'use strict'const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // trueObject.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })delete iLikeMutatingStuffDontI['amICool'] // throws

此类别是最古老、最直接和支持最广泛的属性删除类别。除了字符串之外,它还支持Symbol和数组索引,并且适用于除了第一个版本之外的每个JavaScript版本。但是,它是可变的,违反了一些编程原则并有性能影响。在严格模式下的不可配置属性上使用时,它也可能导致未捕获的异常。

基于休息的字符串属性省略

此类别适用于在需要非可变方法并且您不需要考虑符号键时对较新的ECMAScript风格的普通对象或数组实例进行操作:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }const { name, ...coolio } = foo // coolio doesn't have "name"const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

突变对象属性删除,安全

此类别适用于当您想保留/继续使用原始引用时对对象文字或对象实例进行操作,同时防止在不可配置属性上抛出异常:

'use strict'const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // trueObject.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false

此外,虽然就地突变对象不是无状态的,但您可以使用Reflect.deleteProperty的函数性质来执行delete语句无法实现的部分应用程序和其他函数技术。

基于语法的字符串属性省略

此类别适用于在需要非可变方法并且您不需要考虑符号键时对较新的ECMAScript风格的普通对象或数组实例进行操作:

const foo = { name: 'KIDDDDD!', [Symbol.for('isCool')]: true }const { name, ...coolio } = foo // coolio doesn't have "name"const { isCool, ...coolio2 } = foo // coolio2 has everything from `foo` because `isCool` doesn't account for Symbols :(

基于图书馆的财产遗漏

此类别通常允许更大的功能灵活性,包括考虑符号和在一个语句中省略多个属性:

const o = require("lodash.omit")const foo = { [Symbol.for('a')]: 'abc', b: 'b', c: 'c' }const bar = o(foo, 'a') // "'a' undefined"const baz = o(foo, [ Symbol.for('a'), 'b' ]) // Symbol supported, more than one prop at a time, "Symbol.for('a') undefined"

@约翰斯托克,我们还可以使用JavaScript的原型概念向对象添加方法,以删除调用对象中可用的任何传递的键。

以上答案不胜感激。

var myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*"};
// 1st and direct waydelete myObject.regex; // delete myObject["regex"]console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' }
// 2 way -  by using the concept of JavaScript's prototyping conceptObject.prototype.removeFromObjectByKey = function(key) {// If key exists, remove it and return trueif (this[key] !== undefined) {delete this[key]return true;}// Else return falsereturn false;}
var isRemoved = myObject.removeFromObjectByKey('method')console.log(myObject) // { ircEvent: 'PRIVMSG' }
// More examplesvar obj = {a: 45,b: 56,c: 67}console.log(obj) // { a: 45, b: 56, c: 67 }
// Remove key 'a' from objisRemoved = obj.removeFromObjectByKey('a')console.log(isRemoved); //trueconsole.log(obj); // { b: 56, c: 67 }
// Remove key 'd' from obj which doesn't existvar isRemoved = obj.removeFromObjectByKey('d')console.log(isRemoved); // falseconsole.log(obj); // { b: 56, c: 67 }

扩展语法(ES6)

要完成科恩的回答,如果您想使用扩展语法删除动态变量,您可以这样做:

const key = 'a';
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };
console.log(foo);  // 1console.log(rest); // { b: 2, c: 3 }

*#0将是一个值为#1(即1)的新变量。

扩展答案😇

有几种常见的方法可以从对象中删除属性。
每种方法都有自己的优点和缺点(检查此性能比较):

删除运算符

它可读且简短,但是,如果您对大量对象进行操作,它可能不是最佳选择,因为它的性能没有优化。

delete obj[key];

重新赋值

它比delete快两倍以上,但是属性没有被删除并且可以迭代。

obj[key] = null;obj[key] = false;obj[key] = undefined;

扩展运算符

这个ES6运算符允许我们返回一个全新的对象,不包括任何属性,而不会改变现有对象。缺点是它的性能比上述更差,当需要一次删除许多属性时不建议使用。

{ [key]: val, ...rest } = obj;

要克隆没有属性的对象:

例如:

let object = { a: 1, b: 2, c: 3 };

我们需要删除a

  1. 显式道具密钥

    const { a, ...rest } = object;object = rest;
  2. 可变道具密钥

    const propKey = 'a';const { [propKey]: propValue, ...rest } = object;object = rest;
  3. 一个很酷的箭头函数😎:

    const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest;
    object = removeProperty('a', object);
  4. 对于多个属性

    const removeProperties = (object, ...keys) => (keys.length ? removeProperties(removeProperty(keys.pop(), object), ...keys) : object);

用法

object = removeProperties(object, 'a', 'b') // result => { c: 3 }

<强>或

const propsToRemove = ['a', 'b']object = removeProperties(object, ...propsToRemove) // result => { c: 3 }

您可以使用如下过滤器

var myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*"};
// Way 1
let filter1 = {}Object.keys({...myObject}).filter(d => {if(d !== 'regex'){filter1[d] = myObject[d];}})
console.log(filter1)
// Way 2
let filter2 = Object.fromEntries(Object.entries({...myObject}).filter(d =>d[0] !== 'regex'))
console.log(filter2)

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

obj = Object.fromEntries(Object.entries(myObject).filter(function (m){return m[0] != "regex"/*or whatever key to delete*/}))
console.log(obj)

您也可以使用Object.entries将对象视为a2d数组,并使用拼接删除元素,就像在普通数组中一样,或者简单地过滤对象,就像数组一样,并将重建的对象分配回原始变量

如果您不想修改原始对象。

在不改变对象的情况下删除属性

如果需要考虑可变性,则可以通过复制旧对象中的所有属性来创建一个全新的对象,但要删除的属性除外。

let myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*"};
let prop = 'regex';const updatedObject = Object.keys(myObject).reduce((object, key) => {if (key !== prop) {object[key] = myObject[key]}return object}, {})
console.log(updatedObject);

这里有一个ES6的方法来轻松删除条目:

let myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*"};
const removeItem = 'regex';
const { [removeItem]: remove, ...rest } = myObject;
console.log(remove); // "^http://.*"console.log(rest); // Object { ircEvent: "PRIVMSG", method: "newURI" }

删除对象的两种方法

  1. 使用进行

     function deleteUser(key) {
    const newUsers = {};for (const uid in users) {if (uid !== key) {newUsers[uid] = users[uid];}
    return newUsers}

delete users[key]

有几种方法可以从对象中删除属性:

  1. 使用点属性访问器删除

const myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*",};
delete myObject.regex;console.log(myObject);

  1. 使用方括号删除属性访问器

const myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*",};
delete myObject['regex'];console.log(myObject);// orconst name = 'ircEvent';delete myObject[name];console.log(myObject);

  1. 替代选项,但在不改变原始对象的情况下以不可变的方式,使用对象解构和rest语法。

 const myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*",};
const { regex, ...myObjectRest} = myObject;console.log(myObjectRest); 

我们可以使用

  1. 使用删除object.property
  2. 使用删除对象['属性']
  3. 使用rest,删除多个属性

let myObject = {"ircEvent": "PRIVMSG","method": "newURI","regex": "^http://.*","regex1": "^http://.*","regex2": "^http://.*","regex3": "^http://.*","regex4": "^http://.*"};
delete myObject.regex; // using delete object.property
// Or
delete myObject['regex1']; // using delete object['property']
const { regex2, regex3, regex4, ...newMyObject } = myObject;
console.log(newMyObject);

您可以使用以下命令从对象中删除属性删除属性[键]

在JavaScript中,有两种常见的方法可以从对象中删除属性。

第一种可变方法是使用delete object.property运算符。

第二种方法是不可变的,因为它不修改原始对象,是调用对象解构和扩展语法:const {property, ...rest} = object

简短的回答

var obj = {data: 1,anotherData: 'sample'}delete obj.data //this removes data from the obj

你只剩下

var obj = {anotherData: 'sample'}