给定一个对象:
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
如何删除属性regex
以得到以下的myObject
?
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI"
};
给定一个对象:
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
如何删除属性regex
以得到以下的myObject
?
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI"
};
要从一个对象中删除属性(更改该对象),可以这样做:
delete myObject.regex;
// or,
delete myObject['regex'];
// or,
var prop = "regex";
delete myObject[prop];
Demo
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
delete myObject.regex;
console.log(myObject);
对于任何对此感兴趣的人,Stack Overflow用户 kangax在他们的博客 Understanding delete上写了一篇非常深入的关于delete
语句的博客文章。强烈推荐。
如果您想要一个新的对象,其中包含除某些键之外所有原始键,您可以使用解构。
Demo
let myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
// assign the key regex to the variable _ indicating it will be unused
const {regex: _, ...newObj} = myObject;
console.log(newObj); // has no 'regex' key
console.log(myObject); // remains unchanged
delete
操作符用于逐个删除这些键,通常称为对象属性。
var obj = {
myProperty: 1
}
console.log(obj.hasOwnProperty('myProperty')) // true
delete obj.myProperty
console.log(obj.hasOwnProperty('myProperty')) // false
delete
运算符并不会直接释放内存,它与仅将属性的值赋为 null
或 undefined
不同,因为它会从对象中删除属性本身。请注意,如果被删除属性的值是引用类型(即对象),并且程序的其他部分仍然保留着对该对象的引用,则该对象在所有对它的引用消失之前,当然不会被垃圾回收。
delete
仅适用于描述符标记为可配置的属性。
老问题,现代答案。使用对象解构,一种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 try-out 编辑器中查看它的实际操作。
编辑:
要重新分配给同一变量,请使用 let
:
let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
delete()
更可取?“现代化”并不是一个理由... - GreenAsJadedelete
以前有一些性能问题,但我认为这些问题已经在本页面的其他答案中得到了描述。 - Koen.var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
delete myObject.regex;
console.log(myObject.regex); // logs: undefined
delete
运算符用于从对象中删除属性。const obj = { foo: "bar" };
delete obj.foo;
obj.hasOwnProperty("foo"); // false
请注意,对于数组来说,这与删除元素不是一回事。要从数组中删除一个元素,请使用Array#splice
或Array#pop
。例如:
arr; // [0, 1, 2, 3, 4]
arr.splice(3,1); // 3
arr; // [0, 1, 2, 4]
严格来说,JavaScript中不可能真正删除任何内容。 delete
操作符既不会删除对象也不会释放内存。相反,它将其操作数设置为 undefined
并操纵父对象以使成员消失。
let parent = {
member: { str: "Hello" }
};
let secondref = parent.member;
delete parent.member;
parent.member; // undefined
secondref; // { str: "Hello" }
< p >对象并没有被删除,只是其引用被删除。当所有引用都被移除时,内存才会被垃圾回收器释放。< /p >另一个重要的注意点是,delete
操作符不会为您重新组织结构,这可能会导致看起来不直观的结果。例如,删除数组索引将在其中留下“空洞”。< /p >
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); // false
Array.isArray([1, 2, 3]); // true
在JavaScript中,不同的内置函数对待带有空洞的数组的方式是不同的。
for..in
语句会完全跳过空索引。
一个朴素的 for
循环将返回该索引处的值为 undefined
。
使用 Symbol.iterator
的任何方法都将返回该索引处的值为 undefined
。
forEach
、map
和 reduce
简单地跳过缺失的索引,但不会移除它。
例如:
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
。
Array#splice
会改变数组,并返回任何已删除的索引。deleteCount
个元素从索引start
处移除,并将item1,item2 ... itemN
从索引start
插入到数组中。如果省略deleteCount
,则从startIndex
开始的元素将被删除到数组的末尾。
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.prototype
上还有一个名称类似但不同的函数:Array#slice
。
Array#slice
是非破坏性的,并返回一个新数组,其中包含从start
到end
指定索引的元素。如果未指定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]
Array#pop
会从数组中删除最后一个元素并返回该元素。这个操作会改变数组的长度。相反的操作是push
。
Array#shift
与pop
类似,不同之处在于它删除的是第一个元素。相反的操作是unshift
。
为了补充 Koen 的回答,如果你想使用扩展语法来删除一个动态变量,可以像这样实现:
const key = 'a';
const { [key]: foo, ...rest } = { a: 1, b: 2, c: 3 };
console.log(foo); // 1
console.log(rest); // { b: 2, c: 3 }
* foo
将成为一个新变量,其值为a
(即1)。
有几种常见的方法可以从对象中删除属性。每种方法都有其优缺点(查看此性能比较):
它易于阅读和简短,但如果您正在处理大量对象,则可能不是最佳选择,因为其性能未经优化。
delete obj[key];
它比 delete
快两倍以上,但是该属性不会被删除并且可以进行迭代。
obj[key] = null;
obj[key] = false;
obj[key] = undefined;
这个ES6
操作符允许我们返回一个全新的对象,不包括任何属性,而且不会改变原有的对象。但是它的性能比以上两种方式都要差,因此当您需要一次删除多个属性时,建议不要使用它。
{ [key]: val, ...rest } = obj;
_.pick()
和_.omit()
都返回对象的副本,不会直接修改原始对象。将结果分配给原始对象应该就可以了(未显示)。var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
参考: 链接 _.omit(object, *keys)
返回一个对象的副本,过滤掉被列入黑名单的键(或键数组)。
var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
对于数组,可以类似地使用_.filter()
和_.reject()
。
_.omit(obj, 'key')
is cool but I needed to omit a nested key so I used Object.assign(obj, { filters: { sort_by: '' }})
- agm1984克隆一个没有某个属性的对象:
例如:
let object = { a: 1, b: 2, c: 3 };
我们需要删除a
。
With an explicit prop key:
const { a, ...rest } = object;
object = rest;
With a variable prop key:
const propKey = 'a';
const { [propKey]: propValue, ...rest } = object;
object = rest;
A cool arrow function :
const removeProperty = (propKey, { [propKey]: propValue, ...rest }) => rest;
object = removeProperty('a', object);
For multiple properties
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 }
Parameter 'propKey' implicitly has an 'any' type. ts(7006)
,请为 propKey
添加类型,如下所示:const removeProperty = (propKey: string | number, { [propKey]: propValue, ...rest }) => rest
。 - A-S您在问题标题中使用的术语“从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"];
var
语句创建指向该对象的新引用。关于var
语句的最后一点是我们通常面临的最关键问题之一,因为使用var
语句会防止创建的对象被删除。var
语句创建了“regex”变量,如果您这样做:delete regex; //False
false
,这意味着你的删除语句未按预期执行。但如果你之前没有创建过该变量,且只有myOtherObject["regex"]
作为你最后一个现有的引用,你可以通过以下方式直接删除它:myOtherObject["regex"] = null;
delete myOtherObject["regex"];
更新:
感谢@AgentME:
在删除属性之前将其设置为null没有任何作用(除非对象已被Object.seal密封并且删除失败。这通常不是情况,除非您特别尝试)。
要获取有关Object.seal
的更多信息:Object.seal()
ECMAScript 2015(也称为ES6)引入了内置的Reflect对象。通过调用Reflect.deleteProperty()函数并将目标对象和属性键作为参数,可以删除对象属性:
Reflect.deleteProperty(myJSONObject, 'regex');
这相当于:
delete myJSONObject['regex'];
但是如果对象的属性不可配置,则无论使用deleteProperty函数还是delete运算符都无法删除该属性:
let obj = Object.freeze({ prop: "value" });
let success = Reflect.deleteProperty(obj, "prop");
console.log(success); // false
console.log(obj.prop); // value
Object.freeze() 使对象的所有属性不可配置(除其他之外)。deleteProperty
函数(以及delete operator)在尝试删除其任何属性时返回 false
。如果属性是可配置的,则返回true
,即使该属性不存在。
delete
和 deleteProperty
的区别在于使用严格模式时:
"use strict";
let obj = Object.freeze({ prop: "value" });
Reflect.deleteProperty(obj, "prop"); // false
delete obj["prop"];
// TypeError: property "prop" is non-configurable and can't be deleted
no-unused-vars
规则中的argsIgnorePattern
。这是一个容易解决的问题。 - PartyLich