Say I create an object as follows:
假设我创建一个对象如下所示:
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
What is the best way to remove the property regex
to end up with new myObject
as follows?
删除属性regex以获得如下所示的新myObject的最佳方式是什么?
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI"
};
34 个解决方案
#1
6638
Like this:
是这样的:
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);
For anyone interested in reading more about it, Stack Overflow user kangax has written an incredibly in-depth blog post about the delete
statement on their blog, Understanding delete. It is highly recommended.
对于任何有兴趣阅读更多信息的人来说,Stack Overflow用户kangax已经在他们的博客上写了一篇关于删除声明的非常深入的博文,叫做“理解删除”。这是强烈推荐。
#2
665
Operator delete
is unexpectedly slow!
Look at the benchmark.
看看基准。
Delete is the only true way to remove object's properties without any leftovers, but it works ~ 100 times slower, compared to its "alternative", setting object[key] = undefined
.
删除是删除对象属性的唯一正确方法,没有任何剩余,但是与它的“可选”(设置对象[key] = undefined)相比,它的工作速度要慢100倍。
This alternative is not the correct answer to this question! But, if you use it with care, you can dramatically speed up some algorithms. If you are using delete
in loops and you have problems with performance, read the verbose explanation.
这个选项不是这个问题的正确答案!但是,如果你小心地使用它,你可以显著地加速一些算法。如果在循环中使用delete,并且在性能上有问题,请阅读详细说明。
When should one use delete
and when set value to undefined
?
An object may be seen as a set of key-value pairs. What I call a 'value' is a primitive or a reference to other object, connected to that 'key'.
对象可以看作是键-值对的集合。我所说的“值”是一个原语或其他对象的引用,与那个“键”相连。
Use delete
, when you are passing the result object to the code on which you don't have control (or when you are not sure about your team or yourself).
当您将结果对象传递给您无法控制的代码时(或者当您对您的团队或您自己不确定时),请使用delete。
It deletes the key from the hashmap.
它从hashmap中删除键。
var obj = {
field: 1
};
delete obj.field;
Use setting to undefined
, when you care about performance. It can give a serious boost to your code.
当您关心性能时,使用设置为undefined。它可以对代码有很大的提升。
The key remains on its place in the hashmap, only the value is replaced with undefined
. Understand, that for..in
loop will still iterate over that key.
关键仍然在hashmap中的位置,只有值被未定义的替换。明白,,. .在循环中仍然会迭代那个键。
var obj = {
field: 1
};
obj.field = undefined;
Using this method, not all ways of determining property existence will work as expected.
使用这种方法,并不是所有确定属性存在的方法都能像预期的那样工作。
However, this code:
然而,这段代码:
object.field === undefined
对象。场= = =定义
will behave equivalently for both methods.
这两种方法的行为都是等价的。
Tests
To summarize, differences are all about ways of determining the property existence, and about for..in
loop.
综上所述,差异都是关于确定财产存在的方式,以及关于……在循环。
console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');
console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');
console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');
console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *');
console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');
console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
//Object.keys().indexOf() is an overkill that runs much slower :)
var counter = 0,
key;
for (key in obj) {
counter++;
}
console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');
Beware Of Memory Leaks!
While using obj[prop] = undefined
is faster than doing delete obj[prop]
, another important consideration is that obj[prop] = undefined
may not always be appropriate. delete obj[prop]
removes prop
from obj
and erases it from memory whereas obj[prop] = undefined
simply sets the value of prop
to undefined
which leaves prop
still in memory. Therefore, in circumstances where there are many keys being created and deleted, using obj[prop] = undefined
can force expensive memory reconciliation (causing the page to freeze up) and potentially an out-of-memory error. Examine the following code.
虽然使用obj[prop] = undefined要比删除obj[prop]来得快,但另一个重要的考虑是,obj[prop] = undefined可能并不总是合适的。删除obj[prop]从obj中删除,并将其从内存中删除,而obj[prop] = undefined则简单地将prop的值设置为undefined,从而使prop保持在内存中。因此,在创建和删除许多键的情况下,使用obj[prop] = undefined可能会导致昂贵的内存调节(导致页面冻结)和潜在的内存不足错误。检查下面的代码。
"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
nodeRecords[i] = [];
current = theNodeList[i] = document.createElement("div");
current.textContent = i;
document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
var currentTime = Math.round( performance.now()*1000 )
for (i = 0; i !== numberOfNodes; i++) {
if (lastTime !== -1) {
// the previously collected data is no longer in use
/*************************************************/
/****/ nodeRecords[i][lastTime] = undefined; /****/
/*************************************************/
}
nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
}
lastTime = currentTime;
requestAnimationFrame( recordUpdates );
});
In the code above, simply doing nodeRecords[i][lastTime] = undefined;
will cause a massive memory leak because each animation frame. Each frame, all 65536 DOM elements will take up another 65536 individual slots, but the previous 65536 slots will only be set to undefined which leaves them hanging in the memory. Go ahead, try to run the above code in the console and see for yourself. After forcing an out-of-memory error, attempt to run it again except with the following version of the code that uses the delete
operator instead.
在上面的代码中,只需执行nodeRecords[i][lastTime] = undefined;会导致大量内存泄漏,因为每个动画帧。每一帧,所有的65536 DOM元素都将占用另外的65536个单独的插槽,但是之前的65536插槽将只被设置为未定义的,从而使它们挂在内存中。继续,尝试在控制台运行上面的代码,并亲自查看。在强制执行内存不足错误之后,尝试再次运行它,除非使用delete操作符的代码的以下版本。
"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
nodeRecords[i] = [];
current = theNodeList[i] = document.createElement("div");
current.textContent = i;
document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
var currentTime = Math.round( performance.now()*1000 )
for (i = 0; i !== numberOfNodes; i++) {
if (lastTime !== -1) {
// the previously collected data is no longer in use
/********************************************/
/****/ delete nodeRecords[i][lastTime]; /****/
/********************************************/
}
nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
}
lastTime = currentTime;
requestAnimationFrame( recordUpdates );
});
As seen in the above code snippet, there are some rare appropriate use cases for the delete
operator. However, do not worry about this problem too much. This will only become a problem with long-lifespan objects that get new keys constantly added to them. In any other case (which is almost every case in real-world programming), it is most appropriate to use obj[prop] = undefined
. The main purpose of this section is just to bring this to your attention so that in the rare chance that this does become a problem in your code, then you can more easily understand the problem and thus not have to waste hours dissecting your code to locate and understand this problem.
如上面的代码片段所示,删除操作符有一些罕见的适当用例。但是,不要太担心这个问题。这只会对长寿命的对象产生问题,这些对象会不断地添加新键。在任何其他情况下(在实际编程中几乎都是这样),使用obj[prop] =未定义是最合适的。本节的主要目的是让你的注意力,这样难得的机会,这也成为一个问题在你的代码中,你可以更容易地理解问题,因此不需要浪费时间解剖代码定位和理解这个问题。
Do Not Always Set To undefined
One aspect of Javascript that is important to consider is polymorphism. Polymorphism is when assigning the same variable/slot-in-an-object different types as seen below.
需要考虑的Javascript的一个方面是多态性。多态性是在分配相同的变量/slot-in-an-object类型时,如下面所示。
var foo = "str";
foo = 100; // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text"; // bar is a monomorphic array here because all its entries have the
// same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array
However, there are two major unfixable problems with polymorphic arrays:
然而,多态阵列有两个主要的不可修正的问题:
- They are slow & memory inefficient. When accessing a specific index, instead of just getting the global type for the array, the browser instead has to get the type on a per-index basis whereby each index stores the additional metadata of its type.
- 它们速度慢,内存不足。当访问一个特定的索引,而不是只获取数组的全局类型时,浏览器必须在每个索引的基础上获得类型,这样每个索引就会存储其类型的额外元数据。
- Once polymorphic, always polymorphic. When an array is made polymorphic, the polymorphism cannot be undone in Webkit browsers. So, even if you restore a polymorphic array to being non-polymorphic, it will still be stored by the browser as a polymorphic array.
- 一旦多态,总是多态。当数组被做成多态性时,多态性在Webkit浏览器中无法恢复。所以,即使你将一个多态性数组恢复为非多态性,浏览器仍然会将它存储为一个多态性数组。
One may liken polymorphism to a drug addiction. At first glance, it seems awesomely lucrative: nice pretty fluffy code. Then, the coder introduces their array to the drug of polymorphism. Instantly, the polymorphic array becomes less efficient, and it can never become as efficient as it was before since it is drugged. To correlate such circumstance to real life, someone on cocaine might not even be capable of operating a simple door handle, much less be able to calculate digits of PI. Likewise, an array on the drug of polymorphism cannot ever be as efficient as a monomorphic array.
人们可能把多态性比作吸毒成瘾。乍一看,这似乎是非常有利可图的:漂亮的、非常蓬松的代码。然后,编码器将其阵列引入到多态性药物中。立刻,多态性阵列变得不那么有效了,而且自从被麻醉后,它再也不能像以前那样有效了。为了将这种情况与现实生活联系起来,吸食可卡因的人可能连一个简单的门把手都不会操作,更不用说计算圆周率的数字了。同样,多态性药物的阵列不能像单态阵列一样有效。
But, how does a drug trip analogy relate to the delete
operation? The answer inheres the last line of code in the snippet above. Thus let it be reexamined, this time with a twist.
但是,关于药物旅行的类比与删除操作有什么关系呢?答案继承了上面代码片段中的最后一行代码。因此,让它重新审视,这一次有一个转折。
var bar = ["Some", "example"];
bar[2] = "text"; // bar is not a polymorphic array here because all its entries have the
// same type: string primitive
bar[1] = ""; // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array
Observe. bar[1] = ""
does not coerce polymorphism whereas bar[1] = undefined
does. Therefore, one should always, whenever possible use the corresponding type for their objects so as to not accidentally cause polymorphism. One such person may use the following list as a general reference to get them going. However, please do not explicitly use the below ideas. Instead, use whatever works well for your code.
观察。bar[1] = "不强制多态性,而bar[1] =未定义。因此,在任何可能的情况下,都应该始终为其对象使用相应的类型,以免意外地导致多态性。一个这样的人可以使用下面的列表作为一般的参考来让他们去。但是,请不要明确地使用下面的想法。相反,使用任何对代码有效的方法。
- When using an array/variable typed to the boolean primitive, use either
false
orundefined
as the empty value. While avoiding unnecessary polymorphism is good, rewriting all your code to explicitly forbid it will likely actually result in a decrease in performance. Use common judgement! - 当使用类型为boolean原语的数组/变量时,可以使用false或undefined作为空值。在避免不必要的多态性的同时,重写所有代码,明确禁止它可能会导致性能下降。使用常见的判断!
- When using an array/variable typed to the number primitive, use
0
as the empty value. Note that internally, there are two types of numbers: fast integers (2147483647 to -2147483648 inclusive) and slow floating point doubles (anything other than that includingNaN
andInfinity
). When an integer is demoted to a double, it cannot be promoted back to an integer. - 当使用输入到数字原语的数组/变量时,使用0作为空值。注意,在内部,有两种类型的数字:快速整数(2147483647到-2147483648,包括在内)和慢浮点数加倍(除了NaN和∞)。当一个整数降级为双精度数时,不能将其提升为整数。
- When using an array/variable typed to the string primitive, use
""
as the empty value. - 当使用字符串原语类型的数组/变量时,使用“”作为空值。
- When using a Symbol, wait, why are you using a Symbol?!?! Symbols are bad juju for performance. Everything programmed to use Symbols can be reprogrammed to not use Symbols, resulting in a faster code without Symbols. Symbols are really just super inefficient meta-sugar.
- 使用符号时,等等,你为什么要使用符号?符号对表演来说是不好的。使用符号编程的任何东西都可以重新编程,不使用符号,从而产生没有符号的更快的代码。符号真的是非常低效的元糖。
- When using anything else, use
null
. - 当使用其他东西时,使用null。
However, be mindful! Do not suddenly start doing this with all your preexisting code now as it would likely break such preexisting code and/or introduce strange bugs. Rather, such an efficient practice needs to be implemented from the start, and when converting preexisting code, it is recommended that you double, triple, quadruple check all the lines relating to that as trying to upgrade old code to this new practice can be as risky as it is rewarding.
然而,要注意!现在不要突然开始使用所有已有的代码,因为它可能会破坏这些已存在的代码和/或引入奇怪的bug。相反,这种高效的实践需要从一开始就实现,并且在转换现有代码时,建议您将所有与之相关的代码都翻倍、三倍、四倍检查,因为试图将旧代码升级到这种新实践可能会有风险,因为它是值得的。
#3
186
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
delete myObject.regex;
console.log ( myObject.regex); // logs: undefined
This works in Firefox and Internet Explorer, and I think it works in all others.
这在Firefox和Internet Explorer中都适用,我认为在其他所有浏览器中都适用。
#4
125
As others have said, you can use delete
. But JavaScript is an OOP Language, so everything is an object. Thus, I feel it necessary to point out a particular caveat.
正如其他人所说,您可以使用delete。但是JavaScript是一种OOP语言,所以一切都是对象。因此,我觉得有必要指出一个特别的告诫。
In arrays, unlike plain old objects, using delete
leaves behind garbage in the form of null
, creating a "hole" in the array.
在数组中,与普通的旧对象不同,使用delete以null的形式留下垃圾,在数组中创建一个“洞”。
var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
* Actual result --> [1, 2, null, 4]
*/
As you can see, delete
doesn't always work as one might expect. The value is overwritten, but the memory is not reallocated.
正如您所看到的,delete并不总是像人们期望的那样工作。值被覆盖,但是内存没有被重新分配。
Ignoring the dangers and problems inherent in null
, and the space wasted, this can be problematic if the array needs to be precise.
忽略null中固有的危险和问题,以及浪费的空间,如果数组需要精确的话,这可能会有问题。
For example, say you are creating a webapp that uses JSON-serialization to store an array used for 'tabs' in a string (in this case, localStorage
). Let's also say that the code uses the numerical indices of the array's members to "title" them when drawing to the screen. Why are you doing this rather than just storing the "title" as well? Because... reasons.
例如,假设您正在创建一个webapp,该应用程序使用JSON-serialization将用于“制表符”的数组存储在字符串中(在本例中是localStorage)。我们还可以说,在绘制到屏幕时,代码使用数组成员的数值索引来“标题”它们。你为什么要这么做,而不只是存储“标题”?因为…的原因。
Okay, let's just say that you're trying to save memory at the request of this one user who runs a PDP-11 minicomputer from the 1960's running UNIX, and wrote his own Elinks-based, JavaScript-compliant, line-printer-friendly browser because X11 is out of the question.
好的,我们假设您正在尝试保存内存,这是一个用户的请求,他运行的是1960年代运行的UNIX上的PDP-11小型计算机,并编写了自己的基于elink的、兼容javascript的、行-打印机友好的浏览器,因为X11是不可能的。
Increasingly stupid edge-case scenario aside, using delete
on said array will result in null
polluting the array, and probably causing bugs in the app later on. And if you check for null
, it would straight up skip the numbers resulting in the tabs being rendered like [1] [2] [4] [5] ...
.
把越来越愚蠢的边缘情况放在一边,对上述数组使用delete将导致null污染数组,并可能在以后的应用程序中导致错误。如果你检查零值,它会直接跳过标签导致的数字呈现像[1][2][4][5]....
if (array[index] == null)
continue;
else
title = (index + 1).toString();
/* 0 -> "1"
* 1 -> "2"
* 2 -> (nothing)
* 3 -> "4"
*/
Yeah, that's definitely not what you wanted.
是的,那绝对不是你想要的。
Now, you could keep a second iterator, like j
, to increment only when valid values are read from the array. But that wouldn't exactly solve the null
issue, and you still have to please that troll PDP-11 user. Alas, his computer just doesn't have enough memory to hold that last integer (don't ask how he manages to handle a variable-width array...).
现在,您可以保留第二个迭代器,比如j,只在从数组中读取有效值时才增加。但这并不能完全解决null问题,你仍然需要取悦那个troll PDP-11用户。唉,他的计算机没有足够的内存来保存最后一个整数(不要问他如何处理变宽数组…)
So, he sends you an email in anger:
所以,他愤怒地给你发邮件:
Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found:
>"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]"
After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES!
>var i = index;
>var j = 1;
Grr, I am angry now.
-Troll Davidson
About now, you're at your wit's end. This guy has been complaining non-stop about your app, and you want to tell him to shut up and go get a better computer.
现在,你已经绞尽脑汁了。这家伙一直在抱怨你的应用,你想让他闭嘴,去买一台更好的电脑。
Luckily, arrays do have a specialized method for deleting indices and reallocating memory: Array.prototype.splice()
. You could write something like this:
幸运的是,数组确实有一个专门的方法来删除索引和重新分配内存:Array.prototype.splice()。你可以这样写:
Array.prototype.remove = function(index){
this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]
And just like that, you've pleased Mr. PDP-11. Hooray! (I'd still tell him off, though...)
就这样,你让PDP-11先生很高兴。万岁!(不过我还是要告诉他……)
#5
82
Old question, modern answer. Using object destructuring, an ECMAScript 6 feature, it's as simple as:
老问题,现代的答案。使用ECMAScript 6特性对象解构,很简单:
const { a, ...rest } = { a: 1, b: 2, c: 3 };
Or with the questions sample:
或者用问题样本:
const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);
You can see it in action in the Babel try-out editor.
您可以在Babel try-out编辑器中看到它的作用。
Edit:
编辑:
To reassign to the same variable, use a let
:
要重新分配到相同的变量,请使用let:
let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
#6
60
Another alternative is to use the Underscore.js library.
另一种选择是使用下划线。js库。
Note that _.pick()
and _.omit()
both return a copy of the object and don't directly modify the original object. Assigning the result to the original object should do the trick (not shown).
注意,_.pick()和_.omit()都返回对象的副本,并且不直接修改原始对象。将结果分配给原始对象应该会起到这个作用(没有显示)。
Reference: link _.pick(object, *keys)
参考:链接_。选择(对象,*键)
Return a copy of the object, filtered to only have values for the whitelisted keys (or array of valid keys).
返回对象的一个副本,经过过滤后,该副本只包含白化键的值(或有效键的数组)。
var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
Reference: link _.omit(object, *keys)
参考:链接_。省略(对象,*键)
Return a copy of the object, filtered to omit the blacklisted keys (or array of keys).
返回对象的副本,经过过滤以省略列出的键(或键数组)。
var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
For arrays, _.filter()
and _.reject()
can be used in a similar manner.
对于数组,可以以类似的方式使用_.filter()和_.reject()。
#7
29
The term you have used in your question title Remove a property from a JavaScript object
, can be interpreted in some different ways. The one is to remove it for whole the memory and the list of object keys or the other is just to remove it from your object. As it has been mentioned in some other answers, the delete
keyword is the main part. Let's say you have your object like:
您在问题标题中使用的术语从JavaScript对象中删除属性,可以用不同的方式进行解释。一个是删除整个内存对象键的列表另一个是从对象中删除。正如在其他一些答案中提到的,delete关键字是主要部分。假设你有这样的对象:
myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
If you do:
如果你做的事:
console.log(Object.keys(myJSONObject));
the result would be:
结果将会是:
["ircEvent", "method", "regex"]
You can delete that specific key from your object keys like:
您可以从对象键中删除特定的键,如:
delete myJSONObject["regex"];
Then your objects key using Object.keys(myJSONObject)
would be:
然后使用Object.keys(myJSONObject)的对象键为:
["ircEvent", "method"]
But the point is if you care about memory and you want to whole the object gets removed from the memory, it is recommended to set it to null before you delete the key:
但重点是,如果你关心内存,想要将对象从内存中删除,建议在删除键之前将其设置为null:
myJSONObject["regex"] = null;
delete myJSONObject["regex"];
The other important point here is to be careful about your other references to the same object. For instance, if you create a variable like:
这里的另一个要点是要注意对同一对象的其他引用。例如,如果您创建一个变量,如:
var regex = myJSONObject["regex"];
Or add it as a new pointer to another object like:
或将其添加为指向另一个对象的新指针,如:
var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];
Then even if you remove it from your object myJSONObject
, that specific object won't get deleted from the memory, since the regex
variable and myOtherObject["regex"]
still have their values. Then how could we remove the object from the memory for sure?
然后,即使从对象myJSONObject中删除它,特定的对象也不会从内存中删除,因为regex变量和myOtherObject["regex"]仍然有它们的值。那么,我们如何从内存中删除对象呢?
The answer would be to delete all the references you have in your code, pointed to that very object and also not use var
statements to create new references to that object. This last point regarding var
statements, is one of the most crucial issues that we are usually faced with, because using var
statements would prevent the created object from getting removed.
答案是删除代码中所有引用,指向该对象,并且不使用var语句创建对该对象的新引用。关于var语句的最后一点,是我们通常面临的最关键的问题之一,因为使用var语句可以防止创建的对象被删除。
Which means in this case you won't be able to remove that object because you have created the regex
variable via a var
statement, and if you do:
这意味着,在这种情况下,你无法移除那个对象,因为你通过var语句创建了regex变量,如果你这样做了:
delete regex; //False
The result would be false
, which means that your delete statement haven't been executed as you expected. But if you had not created that variable before, and you only had myOtherObject["regex"]
as your last existing reference, you could have done this just by removing it like:
结果将为false,这意味着您的delete语句没有按预期执行。但是,如果您以前没有创建该变量,并且您只有myOtherObject["regex"]作为您的最后一个现有引用,您可以通过删除它来完成:
myOtherObject["regex"] = null;
delete myOtherObject["regex"];
In other words, a JavaScript object gets killed as soon as there is no reference left in your code pointed to that object.
换句话说,当代码中没有指向该对象的引用时,JavaScript对象就会被杀死。
Update: Thanks to @AgentME:
更新:由于@AgentME:
Setting a property to null before deleting it doesn't accomplish anything (unless the object has been sealed by Object.seal and the delete fails. That's not usually the case unless you specifically try).
在删除属性之前将属性设置为null不会完成任何事情(除非对象被对象密封。密封和删除失败。通常情况下不是这样,除非你特别尝试)。
To get more info on Object.seal
: Object.seal()
获取更多关于对象的信息。密封:Object.seal()
#8
25
ECMAScript 2015 (or ES6) came with built-in Reflect object. It is possible to delete object property by calling Reflect.deleteProperty() function with target object and property key as parameters:
ECMAScript 2015(或ES6)都内置了反射对象。通过调用reflec . deleteproperty()函数,以目标对象和属性键作为参数,可以删除对象属性:
Reflect.deleteProperty(myJSONObject, 'regex');
which is equivalent to:
相当于:
delete myJSONObject['regex'];
But if the property of the object is not configurable it cannot be deleted neither with deleteProperty function nor delete operator:
但若该对象的属性不可配置,则无法使用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() makes all properties of object not configurable (besides other things). deleteProperty
function (as well as delete operator) returns false
when tries to delete any of it's properties. If property is configurable it returns true
, even if property does not exist.
object .freeze()使对象的所有属性都无法配置(除了其他东西)。当尝试删除任何属性时,deleteProperty函数(以及delete操作符)返回false。如果属性是可配置的,则返回true,即使属性不存在。
The difference between delete
and deleteProperty
is when using strict mode:
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
#9
25
Suppose you have an object that looks like this:
假设你有一个像这样的物体:
var Hogwarts = {
staff : [
'Argus Filch',
'Filius Flitwick',
'Gilderoy Lockhart',
'Minerva McGonagall',
'Poppy Pomfrey',
...
],
students : [
'Hannah Abbott',
'Katie Bell',
'Susan Bones',
'Terry Boot',
'Lavender Brown',
...
]
};
Deleting an object property
If you want to use the entire staff
array, the proper way to do this, would be to do this:
如果您想使用整个人员数组,正确的方法是:
delete Hogwarts.staff;
Alternatively, you could also do this:
或者,你也可以这样做:
delete Hogwarts['staff'];
Similarly, removing the entire students array would be done by calling delete Hogwarts.students;
or delete Hogwarts['students'];
.
类似地,删除整个学生数组可以通过调用delete Hogwarts.students来完成;或删除霍格沃茨(“学生”);。
Deleting an array index
Now, if you want to remove a single staff member or student, the procedure is a bit different, because both properties are arrays themselves.
现在,如果您想删除一个职员或学生,那么过程有点不同,因为这两个属性都是数组本身。
If you know the index of your staff member, you could simply do this:
如果你知道你的员工的指数,你可以这样做:
Hogwarts.staff.splice(3, 1);
If you do not know the index, you'll also have to do an index search:
如果你不知道索引,你还必须做索引搜索:
Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);
Note
While you technically can use delete
for an array, using it would result in getting incorrect results when calling for example Hogwarts.staff.length
later on. In other words, delete
would remove the element, but it wouldn't update the value of length
property. Using delete
would also mess up your indexing.
虽然从技术上来说,可以对数组使用delete,但是使用它会在调用Hogwarts.staff之类的时候得到不正确的结果。长度。换句话说,delete将删除元素,但它不会更新length属性的值。使用delete也会弄乱你的索引。
So, when deleting values from an object, always first consider whether you're dealing with object properties or whether you're dealing with array values, and choose the appropriate strategy based on that.
因此,当从对象中删除值时,总是首先考虑是否处理对象属性,或者是否处理数组值,并基于此选择合适的策略。
If you want to experiment with this, you can use this Fiddle as a starting point.
如果你想尝试这个,你可以用这个小提琴作为起点。
#10
20
The delete operator is the best way to do so.
删除操作符是最好的方法。
A live example to show:
一个活生生的例子:
var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
#11
17
I personally use Underscore.js for object and array manipulation:
我个人使用下划线。对象和数组操作的js:
myObject = _.omit(myObject, 'regex');
#12
13
This post is very old and I find it very helpful so I decided to share the unset function I wrote in case someone else see this post and think why it's not so simple as it in PHP unset function.
这篇文章非常古老,我觉得它非常有用,所以我决定分享我写的未设置函数,以防有人看到这篇文章,并思考为什么它没有PHP未设置函数那么简单。
The reason for writing this new unset
function, is to keep the index of all other variables in this hash_map. Look at the following example, and see how the index of "test2" did not change after removing a value from the hash_map.
编写这个新的未设置函数的原因是在hash_map中保留所有其他变量的索引。请看下面的示例,看看在从hash_map中删除一个值之后,“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"}
#13
12
There are a lot of good answers here but I just want to chime in that when using delete to remove a property in JavaScript, it is often wise to first check if that property exists to prevent errors.
这里有很多很好的答案,但是我想指出的是,当使用delete来删除JavaScript中的一个属性时,首先检查该属性是否存在以防止错误通常是明智的。
E.g
如
var obj = {"property":"value", "property2":"value"};
if (obj && obj.hasOwnProperty("property2")) {
delete obj.property2;
} else {
//error handling
}
Due to the dynamic nature of JavaScript there are often cases where you simply don't know if the property exists or not. Checking if obj exists before the && also makes sure you don't throw an error due to calling the hasOwnProperty() function on an undefined object.
由于JavaScript的动态性,您常常不知道属性是否存在。在&&之前检查obj是否存在,还要确保在未定义对象上调用hasOwnProperty()函数时不会抛出错误。
Sorry if this didn't add to your specific use case but I believe this to be a good design to adapt when managing objects and their properties.
对不起,如果这没有添加到您的特定用例中,但我相信这是一个好的设计,以适应管理对象及其属性。
#14
12
Another solution, using 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);
However, it will mutate the original object. If you want to create a new object without the specified key, just assign the reduce function to a new variable, e.g.:
但是,它会使原始对象发生突变。如果您想创建一个没有指定键的新对象,只需将reduce函数赋给一个新变量,例如:
(ES6)
(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);
#15
8
If you want to delete a property deeply nested in the object then you can use the following recursive function with path to the property as the second argument:
如果要删除对象中深度嵌套的属性,可以使用以下递归函数,路径为属性的第二个参数:
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));
else
return false;
}
};
Example:
例子:
var a = {
level1:{
level2:{
level3: {
level4: "yolo"
}
}
}
};
deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);
//Prints {level1: {level2: {}}}
#16
8
Try the following method. Assign the Object
property value to undefined
. Then stringify
the object and parse
.
试试下面的方法。将对象属性值赋给undefined。然后对对象进行字符串化并进行解析。
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));
console.log(myObject);
#17
8
Using ramda#dissoc you will get a new object without the attribute regex
:
使用ramda#dissoc,您将获得一个没有regex属性的新对象:
const newObject = R.dissoc('regex', myObject);
// newObject !== myObject
You can also use other functions to achieve the same effect - omit, pick, ...
您还可以使用其他函数来实现相同的效果——省略、选择、……
#18
7
Using delete method is the best way to do that, as per MDN description, the delete operator removes a property from an object. so you can simply write:
使用delete方法是最好的方法,正如MDN描述的那样,delete操作符从对象中删除属性。所以你可以简单地写:
delete myObject.regex;
// OR
delete myObject['regex'];
The delete operator removes a given property from an object. On successful deletion, it will return true, else false will be returned. However, it is important to consider the following scenarios:
delete操作符从对象中删除给定的属性。如果删除成功,它将返回true,否则将返回false。然而,重要的是考虑以下场景:
If the property which you are trying to delete does not exist, delete will not have any effect and will return true
如果要删除的属性不存在,则delete将没有任何效果,并返回true
If a property with the same name exists on the object's prototype chain, then, after deletion, the object will use the property from the prototype chain (in other words, delete only has an effect on own properties).
如果在对象的原型链上存在同名的属性,那么在删除后,对象将使用来自原型链的属性(换句话说,删除只对自己的属性有影响)。
Any property declared with var cannot be deleted from the global scope or from a function's scope.
不能从全局范围或函数范围中删除使用var声明的任何属性。
As such, delete cannot delete any functions in the global scope (whether this is part from a function definition or a function (expression).
因此,delete不能删除全局范围中的任何函数(无论是函数定义的一部分还是函数(表达式)的一部分)。
Functions which are part of an object (apart from the
global scope) can be deleted with delete.除了全局作用域之外,作为对象一部分的函数可以删除。
Any property declared with let or const cannot be deleted from the scope within which they were defined. Non-configurable properties cannot be removed. This includes properties of built-in objects like Math, Array, Object and properties that are created as non-configurable with methods like Object.defineProperty().
使用let或const声明的任何属性不能从定义它们的范围中删除。无法删除不可配置属性。这包括内置对象的属性,如数学、数组、对象和属性,这些对象都是不可配置的,使用Object. defineproperty()。
The following snippet gives another simple example:
下面的代码片段给出了另一个简单的示例:
var Employee = {
age: 28,
name: 'abc',
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
For more info about and seeing more example, visit the link below:
有关更多信息和更多示例,请访问以下链接:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
#19
3
You can simply delete any property of an object using the delete
keyword.
只需使用delete关键字就可以删除对象的任何属性。
For example:
例如:
var obj = {key1:"val1",key2:"val2",key3:"val3"}
To remove any property, say key1
, use the delete
keyword like this:
要删除任何属性(如key1),请使用delete关键字:
delete obj.key1
Or you can also use array-like notation:
或者你也可以用箭头表示:
delete obj[key1]
Ref: MDN.
裁判:MDN。
#20
3
Dan's assertion that 'delete' is very slow and the benchmark he posted were doubted. So I carried out the test myself in Chrome 59. It does seem that 'delete' is about 30 times slower:
丹的“删除”断言非常缓慢,他发布的基准也受到质疑。所以我自己在Chrome 59进行了测试。似乎“删除”的速度要慢30倍:
var iterationsTotal = 10000000; // 10 million
var 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); // 6135
for (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
Note that I purposedly carried out more than one 'delete' operations in one loop cycle to minimize the effect caused by the other operations.
注意,我特意在一个循环周期中执行了多个“删除”操作,以最小化其他操作带来的影响。
#21
3
Consider creating a new object without the "regex"
property because the original object could always be referenced by other parts of your program. Thus you should avoid manipulating it.
考虑创建一个没有“regex”属性的新对象,因为原始对象总是可以被程序的其他部分引用。因此,您应该避免操纵它。
const myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
const { regex, ...newMyObject } = myObject;
console.log(newMyObject);
#22
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"];
}
}
);
#23
3
Property Removal in JavaScript
There are many different options presented on this page, not because most of the options are wrong—or because the answers are duplicates—but because the appropriate technique depends on the situation you're in and the goals of the tasks you and/or you team are trying to fulfill. To answer you question unequivocally, one needs to know:
在这个页面上有许多不同的选项,不是因为大多数选项是错误的——或者因为答案是重复的——而是因为适当的技术取决于你所处的环境和你和/或你的团队试图完成的任务的目标。要明确地回答你的问题,你需要知道:
- The version of ECMAScript you're targeting
- 你要锁定的ECMAScript版本
- The range of object types you want to remove properties on and the type of property names you need to be able to omit (Strings only? Symbols? Weak references mapped from arbitrary objects? These have all been types of property pointers in JavaScript for years now)
- 想要删除属性的对象类型的范围,以及需要省略的属性名称的类型(仅包含字符串?符号?从任意对象映射的弱引用?这些都是JavaScript中属性指针的类型
- The programming ethos/patterns you and your team use. Do you favor functional approaches and mutation is verboten on your team, or do you employ wild west mutative object-oriented techniques?
- 您和您的团队使用的编程风格/模式。你倾向于功能性的方法,而突变是你的团队中的verboten,或者你是否使用了狂野的西方的突变的面向对象技术?
- Are you looking to achieve this in pure JavaScript or are you willing & able to use a 3rd-party library?
- 您是希望在纯JavaScript中实现这一点,还是您愿意并能够使用第三方库?
Once those four queries have been answered, there are essentially four categories of "property removal" in JavaScript to chose from in order to meet your goals. They are:
一旦回答了这四个查询,在JavaScript中基本上有四种类型的“属性移除”,以满足您的目标。它们是:
Mutative object property deletion, unsafe
This category is for operating on object literals or object instances when you want to retain/continue to use the original reference and aren't using stateless functional principles in your code. An example piece of syntax in this category:
当您希望保留/继续使用原始引用并且在代码中不使用无状态函数原则时,此类别用于对对象文字或对象实例进行操作。这类语法的一个示例:
'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws
This category is the oldest, most straightforward & most widely supported category of property removal. It supports Symbol
& array indexes in addition to strings and works in every version of JavaScript except for the very first release. However, it's mutative which violates some programming principles and has performance implications. It also can result in uncaught exceptions when used on non-configurable properties in strict mode.
这是最古老、最直接和最广泛支持的财产转移类别。除了字符串之外,它还支持符号和数组索引,除了第一个版本外,在每个版本的JavaScript中都可以使用。然而,它是一种突变,它违反了一些编程原则,并且具有性能影响。当在严格模式下使用非可配置属性时,它也会导致未捕获异常。
Rest-based string property omission
This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don't need to account for Symbol keys:
这个类别适用于在普通对象或数组实例上运行的新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 :(
Mutative object property deletion, safe
This category is for operating on object literals or object instances when you want to retain/continue to use the original reference while guarding against exceptions being thrown on unconfigurable properties:
当您想要保留/继续使用原始引用时,该类别是用于对对象文字或对象实例进行操作,同时防止对不可配置属性抛出异常:
'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false
In addition, while mutating objects in-place isn't stateless, you can use the functional nature of Reflect.deleteProperty
to do partial application and other functional techniques that aren't possible with delete
statements.
此外,虽然对现有对象进行修改并不是无状态的,但是可以使用reflec . deleteproperty的功能特性来执行部分应用程序和其他一些在delete语句中不可能实现的功能技术。
Syntax-based string property omission
This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don't need to account for Symbol keys:
这个类别适用于在普通对象或数组实例上运行的新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 :(
Library-based property omission
This category is generally allows for greater functional flexibility, including accounting for Symbols & omitting more than one property in one statement:
这个类别通常允许更大的功能灵活性,包括在一个语句中忽略多个属性:
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"
#24
2
Try this
试试这个
delete myObject['key'];
#25
2
Hello You Can try this simple an sort
你好,你可以试试这个简单的方法。
var obj = [];
obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};
delete(obj.key1);
#26
2
const myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
const { regex, ...other } = myObject;
console.log(myObject)
console.log(regex)
console.log(other)
#27
1
Using lodash
使用lodash
import omit from 'lodash/omit';
const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');
Using Ramda
使用Ramda
R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}
#28
1
you can use the delete
operator as of below.
您可以使用下面的delete操作符。
var multiverse = {
earth1: "Silver Age",
earth2: "Golden Age"
};
delete multiverse.earth2;//will return true if it finds
// Outputs: { earth1: "Silver Age" }
console.log(multiverse);
The delete operator also has a return value.
If it succeeds in deleting a property, it will return true. If it fails to delete a property because the property is unwritable it will return false
, or if in strict mode it will throw an error.
delete操作符还有一个返回值。如果成功删除属性,则返回true。如果因为属性是不可写的而未能删除属性,它将返回false,或者如果在严格模式下,它将抛出一个错误。
#29
1
@johnstock, we can also use JavaScript's prototyping concept to add method to objects to delete any passed key available in calling object.
@johnstock,我们还可以使用JavaScript的原型概念向对象添加方法来删除调用对象中可用的任何传递键。
Above answers are appreciated.
以上答案都感激。
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
// 1st and direct way
delete myObject.regex; // delete myObject["regex"]
console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' }
// 2 way - by using the concept of JavaScript's prototyping concept
Object.prototype.removeFromObjectByKey = function(key) {
// If key exists, remove it and return true
if(this[key] !== undefined) {
delete this[key]
return true;
}
// Else return false
return false;
}
var isRemoved =
myObject.removeFromObjectByKey('method')
console.log(myObject) // { ircEvent: 'PRIVMSG' }
// More examples
var obj = { a: 45, b: 56, c: 67}
console.log(obj) // { a: 45, b: 56, c: 67 }
// Remove key 'a' from obj
isRemoved = obj.removeFromObjectByKey('a')
console.log(isRemoved); //true
console.log(obj); // { b: 56, c: 67 }
// Remove key 'd' from obj which doesn't exist
var isRemoved = obj.removeFromObjectByKey('d')
console.log(isRemoved); // false
console.log(obj); // { b: 56, c: 67 }
#30
0
Very simple:
非常简单:
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
delete myObject.regex;
#1
6638
Like this:
是这样的:
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);
For anyone interested in reading more about it, Stack Overflow user kangax has written an incredibly in-depth blog post about the delete
statement on their blog, Understanding delete. It is highly recommended.
对于任何有兴趣阅读更多信息的人来说,Stack Overflow用户kangax已经在他们的博客上写了一篇关于删除声明的非常深入的博文,叫做“理解删除”。这是强烈推荐。
#2
665
Operator delete
is unexpectedly slow!
Look at the benchmark.
看看基准。
Delete is the only true way to remove object's properties without any leftovers, but it works ~ 100 times slower, compared to its "alternative", setting object[key] = undefined
.
删除是删除对象属性的唯一正确方法,没有任何剩余,但是与它的“可选”(设置对象[key] = undefined)相比,它的工作速度要慢100倍。
This alternative is not the correct answer to this question! But, if you use it with care, you can dramatically speed up some algorithms. If you are using delete
in loops and you have problems with performance, read the verbose explanation.
这个选项不是这个问题的正确答案!但是,如果你小心地使用它,你可以显著地加速一些算法。如果在循环中使用delete,并且在性能上有问题,请阅读详细说明。
When should one use delete
and when set value to undefined
?
An object may be seen as a set of key-value pairs. What I call a 'value' is a primitive or a reference to other object, connected to that 'key'.
对象可以看作是键-值对的集合。我所说的“值”是一个原语或其他对象的引用,与那个“键”相连。
Use delete
, when you are passing the result object to the code on which you don't have control (or when you are not sure about your team or yourself).
当您将结果对象传递给您无法控制的代码时(或者当您对您的团队或您自己不确定时),请使用delete。
It deletes the key from the hashmap.
它从hashmap中删除键。
var obj = {
field: 1
};
delete obj.field;
Use setting to undefined
, when you care about performance. It can give a serious boost to your code.
当您关心性能时,使用设置为undefined。它可以对代码有很大的提升。
The key remains on its place in the hashmap, only the value is replaced with undefined
. Understand, that for..in
loop will still iterate over that key.
关键仍然在hashmap中的位置,只有值被未定义的替换。明白,,. .在循环中仍然会迭代那个键。
var obj = {
field: 1
};
obj.field = undefined;
Using this method, not all ways of determining property existence will work as expected.
使用这种方法,并不是所有确定属性存在的方法都能像预期的那样工作。
However, this code:
然而,这段代码:
object.field === undefined
对象。场= = =定义
will behave equivalently for both methods.
这两种方法的行为都是等价的。
Tests
To summarize, differences are all about ways of determining the property existence, and about for..in
loop.
综上所述,差异都是关于确定财产存在的方式,以及关于……在循环。
console.log('* -> "Takes prototype inheritance into consideration, that means it lookups all over prototype chain too."');
console.log(obj.field === undefined, 'obj.field === undefined', 'You get "undefined" value when querying for "field" in object-hashmap. *');
console.log(obj["field"] === undefined, 'obj["field"] === undefined', 'Just another way to query (equivalent). *');
console.log(typeof obj.field === "undefined", 'typeof obj.field === "undefined"', 'Get the value attached to "field" key, and check it\'s type is "undefined". *');
console.log("field" in obj, '"field" in obj', 'This statement returns true if "field" key exists in the hashmap. False otherwise. *');
console.log(obj.hasOwnProperty("field"), 'obj.hasOwnProperty("field")', 'This statement returns true if \'field\' key exists in the hashmap. The ONLY way NOT to lookup for property in the prototype chain!');
//Object.keys().indexOf() is an overkill that runs much slower :)
var counter = 0,
key;
for (key in obj) {
counter++;
}
console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');
Beware Of Memory Leaks!
While using obj[prop] = undefined
is faster than doing delete obj[prop]
, another important consideration is that obj[prop] = undefined
may not always be appropriate. delete obj[prop]
removes prop
from obj
and erases it from memory whereas obj[prop] = undefined
simply sets the value of prop
to undefined
which leaves prop
still in memory. Therefore, in circumstances where there are many keys being created and deleted, using obj[prop] = undefined
can force expensive memory reconciliation (causing the page to freeze up) and potentially an out-of-memory error. Examine the following code.
虽然使用obj[prop] = undefined要比删除obj[prop]来得快,但另一个重要的考虑是,obj[prop] = undefined可能并不总是合适的。删除obj[prop]从obj中删除,并将其从内存中删除,而obj[prop] = undefined则简单地将prop的值设置为undefined,从而使prop保持在内存中。因此,在创建和删除许多键的情况下,使用obj[prop] = undefined可能会导致昂贵的内存调节(导致页面冻结)和潜在的内存不足错误。检查下面的代码。
"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
nodeRecords[i] = [];
current = theNodeList[i] = document.createElement("div");
current.textContent = i;
document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
var currentTime = Math.round( performance.now()*1000 )
for (i = 0; i !== numberOfNodes; i++) {
if (lastTime !== -1) {
// the previously collected data is no longer in use
/*************************************************/
/****/ nodeRecords[i][lastTime] = undefined; /****/
/*************************************************/
}
nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
}
lastTime = currentTime;
requestAnimationFrame( recordUpdates );
});
In the code above, simply doing nodeRecords[i][lastTime] = undefined;
will cause a massive memory leak because each animation frame. Each frame, all 65536 DOM elements will take up another 65536 individual slots, but the previous 65536 slots will only be set to undefined which leaves them hanging in the memory. Go ahead, try to run the above code in the console and see for yourself. After forcing an out-of-memory error, attempt to run it again except with the following version of the code that uses the delete
operator instead.
在上面的代码中,只需执行nodeRecords[i][lastTime] = undefined;会导致大量内存泄漏,因为每个动画帧。每一帧,所有的65536 DOM元素都将占用另外的65536个单独的插槽,但是之前的65536插槽将只被设置为未定义的,从而使它们挂在内存中。继续,尝试在控制台运行上面的代码,并亲自查看。在强制执行内存不足错误之后,尝试再次运行它,除非使用delete操作符的代码的以下版本。
"use strict";
var theNodeList=[], i, current, numberOfNodes=65536, body=document.body, nodeRecords=[];
for (i = 0; i !== numberOfNodes; i++) {
nodeRecords[i] = [];
current = theNodeList[i] = document.createElement("div");
current.textContent = i;
document.body.appendChild( current );
}
var lastTime = -1;
requestAnimationFrame(function recordUpdates(){
var currentTime = Math.round( performance.now()*1000 )
for (i = 0; i !== numberOfNodes; i++) {
if (lastTime !== -1) {
// the previously collected data is no longer in use
/********************************************/
/****/ delete nodeRecords[i][lastTime]; /****/
/********************************************/
}
nodeRecords[i][currentTime] = theNodeList[i].outerHTML;
}
lastTime = currentTime;
requestAnimationFrame( recordUpdates );
});
As seen in the above code snippet, there are some rare appropriate use cases for the delete
operator. However, do not worry about this problem too much. This will only become a problem with long-lifespan objects that get new keys constantly added to them. In any other case (which is almost every case in real-world programming), it is most appropriate to use obj[prop] = undefined
. The main purpose of this section is just to bring this to your attention so that in the rare chance that this does become a problem in your code, then you can more easily understand the problem and thus not have to waste hours dissecting your code to locate and understand this problem.
如上面的代码片段所示,删除操作符有一些罕见的适当用例。但是,不要太担心这个问题。这只会对长寿命的对象产生问题,这些对象会不断地添加新键。在任何其他情况下(在实际编程中几乎都是这样),使用obj[prop] =未定义是最合适的。本节的主要目的是让你的注意力,这样难得的机会,这也成为一个问题在你的代码中,你可以更容易地理解问题,因此不需要浪费时间解剖代码定位和理解这个问题。
Do Not Always Set To undefined
One aspect of Javascript that is important to consider is polymorphism. Polymorphism is when assigning the same variable/slot-in-an-object different types as seen below.
需要考虑的Javascript的一个方面是多态性。多态性是在分配相同的变量/slot-in-an-object类型时,如下面所示。
var foo = "str";
foo = 100; // variable foo is now labeled polymorphic by the browser
var bar = ["Some", "example"];
bar[2] = "text"; // bar is a monomorphic array here because all its entries have the
// same type: string primitive
bar[1] = undefined; // bar is now a polymorphic array
However, there are two major unfixable problems with polymorphic arrays:
然而,多态阵列有两个主要的不可修正的问题:
- They are slow & memory inefficient. When accessing a specific index, instead of just getting the global type for the array, the browser instead has to get the type on a per-index basis whereby each index stores the additional metadata of its type.
- 它们速度慢,内存不足。当访问一个特定的索引,而不是只获取数组的全局类型时,浏览器必须在每个索引的基础上获得类型,这样每个索引就会存储其类型的额外元数据。
- Once polymorphic, always polymorphic. When an array is made polymorphic, the polymorphism cannot be undone in Webkit browsers. So, even if you restore a polymorphic array to being non-polymorphic, it will still be stored by the browser as a polymorphic array.
- 一旦多态,总是多态。当数组被做成多态性时,多态性在Webkit浏览器中无法恢复。所以,即使你将一个多态性数组恢复为非多态性,浏览器仍然会将它存储为一个多态性数组。
One may liken polymorphism to a drug addiction. At first glance, it seems awesomely lucrative: nice pretty fluffy code. Then, the coder introduces their array to the drug of polymorphism. Instantly, the polymorphic array becomes less efficient, and it can never become as efficient as it was before since it is drugged. To correlate such circumstance to real life, someone on cocaine might not even be capable of operating a simple door handle, much less be able to calculate digits of PI. Likewise, an array on the drug of polymorphism cannot ever be as efficient as a monomorphic array.
人们可能把多态性比作吸毒成瘾。乍一看,这似乎是非常有利可图的:漂亮的、非常蓬松的代码。然后,编码器将其阵列引入到多态性药物中。立刻,多态性阵列变得不那么有效了,而且自从被麻醉后,它再也不能像以前那样有效了。为了将这种情况与现实生活联系起来,吸食可卡因的人可能连一个简单的门把手都不会操作,更不用说计算圆周率的数字了。同样,多态性药物的阵列不能像单态阵列一样有效。
But, how does a drug trip analogy relate to the delete
operation? The answer inheres the last line of code in the snippet above. Thus let it be reexamined, this time with a twist.
但是,关于药物旅行的类比与删除操作有什么关系呢?答案继承了上面代码片段中的最后一行代码。因此,让它重新审视,这一次有一个转折。
var bar = ["Some", "example"];
bar[2] = "text"; // bar is not a polymorphic array here because all its entries have the
// same type: string primitive
bar[1] = ""; // bar is still a monomorphic array
bar[1] = undefined; // bar is now a polymorphic array
Observe. bar[1] = ""
does not coerce polymorphism whereas bar[1] = undefined
does. Therefore, one should always, whenever possible use the corresponding type for their objects so as to not accidentally cause polymorphism. One such person may use the following list as a general reference to get them going. However, please do not explicitly use the below ideas. Instead, use whatever works well for your code.
观察。bar[1] = "不强制多态性,而bar[1] =未定义。因此,在任何可能的情况下,都应该始终为其对象使用相应的类型,以免意外地导致多态性。一个这样的人可以使用下面的列表作为一般的参考来让他们去。但是,请不要明确地使用下面的想法。相反,使用任何对代码有效的方法。
- When using an array/variable typed to the boolean primitive, use either
false
orundefined
as the empty value. While avoiding unnecessary polymorphism is good, rewriting all your code to explicitly forbid it will likely actually result in a decrease in performance. Use common judgement! - 当使用类型为boolean原语的数组/变量时,可以使用false或undefined作为空值。在避免不必要的多态性的同时,重写所有代码,明确禁止它可能会导致性能下降。使用常见的判断!
- When using an array/variable typed to the number primitive, use
0
as the empty value. Note that internally, there are two types of numbers: fast integers (2147483647 to -2147483648 inclusive) and slow floating point doubles (anything other than that includingNaN
andInfinity
). When an integer is demoted to a double, it cannot be promoted back to an integer. - 当使用输入到数字原语的数组/变量时,使用0作为空值。注意,在内部,有两种类型的数字:快速整数(2147483647到-2147483648,包括在内)和慢浮点数加倍(除了NaN和∞)。当一个整数降级为双精度数时,不能将其提升为整数。
- When using an array/variable typed to the string primitive, use
""
as the empty value. - 当使用字符串原语类型的数组/变量时,使用“”作为空值。
- When using a Symbol, wait, why are you using a Symbol?!?! Symbols are bad juju for performance. Everything programmed to use Symbols can be reprogrammed to not use Symbols, resulting in a faster code without Symbols. Symbols are really just super inefficient meta-sugar.
- 使用符号时,等等,你为什么要使用符号?符号对表演来说是不好的。使用符号编程的任何东西都可以重新编程,不使用符号,从而产生没有符号的更快的代码。符号真的是非常低效的元糖。
- When using anything else, use
null
. - 当使用其他东西时,使用null。
However, be mindful! Do not suddenly start doing this with all your preexisting code now as it would likely break such preexisting code and/or introduce strange bugs. Rather, such an efficient practice needs to be implemented from the start, and when converting preexisting code, it is recommended that you double, triple, quadruple check all the lines relating to that as trying to upgrade old code to this new practice can be as risky as it is rewarding.
然而,要注意!现在不要突然开始使用所有已有的代码,因为它可能会破坏这些已存在的代码和/或引入奇怪的bug。相反,这种高效的实践需要从一开始就实现,并且在转换现有代码时,建议您将所有与之相关的代码都翻倍、三倍、四倍检查,因为试图将旧代码升级到这种新实践可能会有风险,因为它是值得的。
#3
186
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
delete myObject.regex;
console.log ( myObject.regex); // logs: undefined
This works in Firefox and Internet Explorer, and I think it works in all others.
这在Firefox和Internet Explorer中都适用,我认为在其他所有浏览器中都适用。
#4
125
As others have said, you can use delete
. But JavaScript is an OOP Language, so everything is an object. Thus, I feel it necessary to point out a particular caveat.
正如其他人所说,您可以使用delete。但是JavaScript是一种OOP语言,所以一切都是对象。因此,我觉得有必要指出一个特别的告诫。
In arrays, unlike plain old objects, using delete
leaves behind garbage in the form of null
, creating a "hole" in the array.
在数组中,与普通的旧对象不同,使用delete以null的形式留下垃圾,在数组中创建一个“洞”。
var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
* Actual result --> [1, 2, null, 4]
*/
As you can see, delete
doesn't always work as one might expect. The value is overwritten, but the memory is not reallocated.
正如您所看到的,delete并不总是像人们期望的那样工作。值被覆盖,但是内存没有被重新分配。
Ignoring the dangers and problems inherent in null
, and the space wasted, this can be problematic if the array needs to be precise.
忽略null中固有的危险和问题,以及浪费的空间,如果数组需要精确的话,这可能会有问题。
For example, say you are creating a webapp that uses JSON-serialization to store an array used for 'tabs' in a string (in this case, localStorage
). Let's also say that the code uses the numerical indices of the array's members to "title" them when drawing to the screen. Why are you doing this rather than just storing the "title" as well? Because... reasons.
例如,假设您正在创建一个webapp,该应用程序使用JSON-serialization将用于“制表符”的数组存储在字符串中(在本例中是localStorage)。我们还可以说,在绘制到屏幕时,代码使用数组成员的数值索引来“标题”它们。你为什么要这么做,而不只是存储“标题”?因为…的原因。
Okay, let's just say that you're trying to save memory at the request of this one user who runs a PDP-11 minicomputer from the 1960's running UNIX, and wrote his own Elinks-based, JavaScript-compliant, line-printer-friendly browser because X11 is out of the question.
好的,我们假设您正在尝试保存内存,这是一个用户的请求,他运行的是1960年代运行的UNIX上的PDP-11小型计算机,并编写了自己的基于elink的、兼容javascript的、行-打印机友好的浏览器,因为X11是不可能的。
Increasingly stupid edge-case scenario aside, using delete
on said array will result in null
polluting the array, and probably causing bugs in the app later on. And if you check for null
, it would straight up skip the numbers resulting in the tabs being rendered like [1] [2] [4] [5] ...
.
把越来越愚蠢的边缘情况放在一边,对上述数组使用delete将导致null污染数组,并可能在以后的应用程序中导致错误。如果你检查零值,它会直接跳过标签导致的数字呈现像[1][2][4][5]....
if (array[index] == null)
continue;
else
title = (index + 1).toString();
/* 0 -> "1"
* 1 -> "2"
* 2 -> (nothing)
* 3 -> "4"
*/
Yeah, that's definitely not what you wanted.
是的,那绝对不是你想要的。
Now, you could keep a second iterator, like j
, to increment only when valid values are read from the array. But that wouldn't exactly solve the null
issue, and you still have to please that troll PDP-11 user. Alas, his computer just doesn't have enough memory to hold that last integer (don't ask how he manages to handle a variable-width array...).
现在,您可以保留第二个迭代器,比如j,只在从数组中读取有效值时才增加。但这并不能完全解决null问题,你仍然需要取悦那个troll PDP-11用户。唉,他的计算机没有足够的内存来保存最后一个整数(不要问他如何处理变宽数组…)
So, he sends you an email in anger:
所以,他愤怒地给你发邮件:
Hey, your webapp broke my browser! I checked my localStorage database after your stupid code made my browser segfault, and this is what I found:
>"tabs:['Hello World', 'foo bar baz', null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, ... ]"
After clearing my precious data, it segfaulted again, and I did a backtrace, and what do I find? WHAT DO I FIND!? YOU USE TOO MANY VARIABLES!
>var i = index;
>var j = 1;
Grr, I am angry now.
-Troll Davidson
About now, you're at your wit's end. This guy has been complaining non-stop about your app, and you want to tell him to shut up and go get a better computer.
现在,你已经绞尽脑汁了。这家伙一直在抱怨你的应用,你想让他闭嘴,去买一台更好的电脑。
Luckily, arrays do have a specialized method for deleting indices and reallocating memory: Array.prototype.splice()
. You could write something like this:
幸运的是,数组确实有一个专门的方法来删除索引和重新分配内存:Array.prototype.splice()。你可以这样写:
Array.prototype.remove = function(index){
this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]
And just like that, you've pleased Mr. PDP-11. Hooray! (I'd still tell him off, though...)
就这样,你让PDP-11先生很高兴。万岁!(不过我还是要告诉他……)
#5
82
Old question, modern answer. Using object destructuring, an ECMAScript 6 feature, it's as simple as:
老问题,现代的答案。使用ECMAScript 6特性对象解构,很简单:
const { a, ...rest } = { a: 1, b: 2, c: 3 };
Or with the questions sample:
或者用问题样本:
const myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
const { regex, ...newObject } = myObject;
console.log(newObject);
You can see it in action in the Babel try-out editor.
您可以在Babel try-out编辑器中看到它的作用。
Edit:
编辑:
To reassign to the same variable, use a let
:
要重新分配到相同的变量,请使用let:
let myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
({ regex, ...myObject } = myObject);
console.log(myObject);
#6
60
Another alternative is to use the Underscore.js library.
另一种选择是使用下划线。js库。
Note that _.pick()
and _.omit()
both return a copy of the object and don't directly modify the original object. Assigning the result to the original object should do the trick (not shown).
注意,_.pick()和_.omit()都返回对象的副本,并且不直接修改原始对象。将结果分配给原始对象应该会起到这个作用(没有显示)。
Reference: link _.pick(object, *keys)
参考:链接_。选择(对象,*键)
Return a copy of the object, filtered to only have values for the whitelisted keys (or array of valid keys).
返回对象的一个副本,经过过滤后,该副本只包含白化键的值(或有效键的数组)。
var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.pick(myJSONObject, "ircEvent", "method");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
Reference: link _.omit(object, *keys)
参考:链接_。省略(对象,*键)
Return a copy of the object, filtered to omit the blacklisted keys (or array of keys).
返回对象的副本,经过过滤以省略列出的键(或键数组)。
var myJSONObject =
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
_.omit(myJSONObject, "regex");
=> {"ircEvent": "PRIVMSG", "method": "newURI"};
For arrays, _.filter()
and _.reject()
can be used in a similar manner.
对于数组,可以以类似的方式使用_.filter()和_.reject()。
#7
29
The term you have used in your question title Remove a property from a JavaScript object
, can be interpreted in some different ways. The one is to remove it for whole the memory and the list of object keys or the other is just to remove it from your object. As it has been mentioned in some other answers, the delete
keyword is the main part. Let's say you have your object like:
您在问题标题中使用的术语从JavaScript对象中删除属性,可以用不同的方式进行解释。一个是删除整个内存对象键的列表另一个是从对象中删除。正如在其他一些答案中提到的,delete关键字是主要部分。假设你有这样的对象:
myJSONObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
If you do:
如果你做的事:
console.log(Object.keys(myJSONObject));
the result would be:
结果将会是:
["ircEvent", "method", "regex"]
You can delete that specific key from your object keys like:
您可以从对象键中删除特定的键,如:
delete myJSONObject["regex"];
Then your objects key using Object.keys(myJSONObject)
would be:
然后使用Object.keys(myJSONObject)的对象键为:
["ircEvent", "method"]
But the point is if you care about memory and you want to whole the object gets removed from the memory, it is recommended to set it to null before you delete the key:
但重点是,如果你关心内存,想要将对象从内存中删除,建议在删除键之前将其设置为null:
myJSONObject["regex"] = null;
delete myJSONObject["regex"];
The other important point here is to be careful about your other references to the same object. For instance, if you create a variable like:
这里的另一个要点是要注意对同一对象的其他引用。例如,如果您创建一个变量,如:
var regex = myJSONObject["regex"];
Or add it as a new pointer to another object like:
或将其添加为指向另一个对象的新指针,如:
var myOtherObject = {};
myOtherObject["regex"] = myJSONObject["regex"];
Then even if you remove it from your object myJSONObject
, that specific object won't get deleted from the memory, since the regex
variable and myOtherObject["regex"]
still have their values. Then how could we remove the object from the memory for sure?
然后,即使从对象myJSONObject中删除它,特定的对象也不会从内存中删除,因为regex变量和myOtherObject["regex"]仍然有它们的值。那么,我们如何从内存中删除对象呢?
The answer would be to delete all the references you have in your code, pointed to that very object and also not use var
statements to create new references to that object. This last point regarding var
statements, is one of the most crucial issues that we are usually faced with, because using var
statements would prevent the created object from getting removed.
答案是删除代码中所有引用,指向该对象,并且不使用var语句创建对该对象的新引用。关于var语句的最后一点,是我们通常面临的最关键的问题之一,因为使用var语句可以防止创建的对象被删除。
Which means in this case you won't be able to remove that object because you have created the regex
variable via a var
statement, and if you do:
这意味着,在这种情况下,你无法移除那个对象,因为你通过var语句创建了regex变量,如果你这样做了:
delete regex; //False
The result would be false
, which means that your delete statement haven't been executed as you expected. But if you had not created that variable before, and you only had myOtherObject["regex"]
as your last existing reference, you could have done this just by removing it like:
结果将为false,这意味着您的delete语句没有按预期执行。但是,如果您以前没有创建该变量,并且您只有myOtherObject["regex"]作为您的最后一个现有引用,您可以通过删除它来完成:
myOtherObject["regex"] = null;
delete myOtherObject["regex"];
In other words, a JavaScript object gets killed as soon as there is no reference left in your code pointed to that object.
换句话说,当代码中没有指向该对象的引用时,JavaScript对象就会被杀死。
Update: Thanks to @AgentME:
更新:由于@AgentME:
Setting a property to null before deleting it doesn't accomplish anything (unless the object has been sealed by Object.seal and the delete fails. That's not usually the case unless you specifically try).
在删除属性之前将属性设置为null不会完成任何事情(除非对象被对象密封。密封和删除失败。通常情况下不是这样,除非你特别尝试)。
To get more info on Object.seal
: Object.seal()
获取更多关于对象的信息。密封:Object.seal()
#8
25
ECMAScript 2015 (or ES6) came with built-in Reflect object. It is possible to delete object property by calling Reflect.deleteProperty() function with target object and property key as parameters:
ECMAScript 2015(或ES6)都内置了反射对象。通过调用reflec . deleteproperty()函数,以目标对象和属性键作为参数,可以删除对象属性:
Reflect.deleteProperty(myJSONObject, 'regex');
which is equivalent to:
相当于:
delete myJSONObject['regex'];
But if the property of the object is not configurable it cannot be deleted neither with deleteProperty function nor delete operator:
但若该对象的属性不可配置,则无法使用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() makes all properties of object not configurable (besides other things). deleteProperty
function (as well as delete operator) returns false
when tries to delete any of it's properties. If property is configurable it returns true
, even if property does not exist.
object .freeze()使对象的所有属性都无法配置(除了其他东西)。当尝试删除任何属性时,deleteProperty函数(以及delete操作符)返回false。如果属性是可配置的,则返回true,即使属性不存在。
The difference between delete
and deleteProperty
is when using strict mode:
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
#9
25
Suppose you have an object that looks like this:
假设你有一个像这样的物体:
var Hogwarts = {
staff : [
'Argus Filch',
'Filius Flitwick',
'Gilderoy Lockhart',
'Minerva McGonagall',
'Poppy Pomfrey',
...
],
students : [
'Hannah Abbott',
'Katie Bell',
'Susan Bones',
'Terry Boot',
'Lavender Brown',
...
]
};
Deleting an object property
If you want to use the entire staff
array, the proper way to do this, would be to do this:
如果您想使用整个人员数组,正确的方法是:
delete Hogwarts.staff;
Alternatively, you could also do this:
或者,你也可以这样做:
delete Hogwarts['staff'];
Similarly, removing the entire students array would be done by calling delete Hogwarts.students;
or delete Hogwarts['students'];
.
类似地,删除整个学生数组可以通过调用delete Hogwarts.students来完成;或删除霍格沃茨(“学生”);。
Deleting an array index
Now, if you want to remove a single staff member or student, the procedure is a bit different, because both properties are arrays themselves.
现在,如果您想删除一个职员或学生,那么过程有点不同,因为这两个属性都是数组本身。
If you know the index of your staff member, you could simply do this:
如果你知道你的员工的指数,你可以这样做:
Hogwarts.staff.splice(3, 1);
If you do not know the index, you'll also have to do an index search:
如果你不知道索引,你还必须做索引搜索:
Hogwarts.staff.splice(Hogwarts.staff.indexOf('Minerva McGonnagall') - 1, 1);
Note
While you technically can use delete
for an array, using it would result in getting incorrect results when calling for example Hogwarts.staff.length
later on. In other words, delete
would remove the element, but it wouldn't update the value of length
property. Using delete
would also mess up your indexing.
虽然从技术上来说,可以对数组使用delete,但是使用它会在调用Hogwarts.staff之类的时候得到不正确的结果。长度。换句话说,delete将删除元素,但它不会更新length属性的值。使用delete也会弄乱你的索引。
So, when deleting values from an object, always first consider whether you're dealing with object properties or whether you're dealing with array values, and choose the appropriate strategy based on that.
因此,当从对象中删除值时,总是首先考虑是否处理对象属性,或者是否处理数组值,并基于此选择合适的策略。
If you want to experiment with this, you can use this Fiddle as a starting point.
如果你想尝试这个,你可以用这个小提琴作为起点。
#10
20
The delete operator is the best way to do so.
删除操作符是最好的方法。
A live example to show:
一个活生生的例子:
var foo = {bar: 'bar'};
delete foo.bar;
console.log('bar' in foo); // Logs false, because bar was deleted from foo.
#11
17
I personally use Underscore.js for object and array manipulation:
我个人使用下划线。对象和数组操作的js:
myObject = _.omit(myObject, 'regex');
#12
13
This post is very old and I find it very helpful so I decided to share the unset function I wrote in case someone else see this post and think why it's not so simple as it in PHP unset function.
这篇文章非常古老,我觉得它非常有用,所以我决定分享我写的未设置函数,以防有人看到这篇文章,并思考为什么它没有PHP未设置函数那么简单。
The reason for writing this new unset
function, is to keep the index of all other variables in this hash_map. Look at the following example, and see how the index of "test2" did not change after removing a value from the hash_map.
编写这个新的未设置函数的原因是在hash_map中保留所有其他变量的索引。请看下面的示例,看看在从hash_map中删除一个值之后,“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"}
#13
12
There are a lot of good answers here but I just want to chime in that when using delete to remove a property in JavaScript, it is often wise to first check if that property exists to prevent errors.
这里有很多很好的答案,但是我想指出的是,当使用delete来删除JavaScript中的一个属性时,首先检查该属性是否存在以防止错误通常是明智的。
E.g
如
var obj = {"property":"value", "property2":"value"};
if (obj && obj.hasOwnProperty("property2")) {
delete obj.property2;
} else {
//error handling
}
Due to the dynamic nature of JavaScript there are often cases where you simply don't know if the property exists or not. Checking if obj exists before the && also makes sure you don't throw an error due to calling the hasOwnProperty() function on an undefined object.
由于JavaScript的动态性,您常常不知道属性是否存在。在&&之前检查obj是否存在,还要确保在未定义对象上调用hasOwnProperty()函数时不会抛出错误。
Sorry if this didn't add to your specific use case but I believe this to be a good design to adapt when managing objects and their properties.
对不起,如果这没有添加到您的特定用例中,但我相信这是一个好的设计,以适应管理对象及其属性。
#14
12
Another solution, using 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);
However, it will mutate the original object. If you want to create a new object without the specified key, just assign the reduce function to a new variable, e.g.:
但是,它会使原始对象发生突变。如果您想创建一个没有指定键的新对象,只需将reduce函数赋给一个新变量,例如:
(ES6)
(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);
#15
8
If you want to delete a property deeply nested in the object then you can use the following recursive function with path to the property as the second argument:
如果要删除对象中深度嵌套的属性,可以使用以下递归函数,路径为属性的第二个参数:
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));
else
return false;
}
};
Example:
例子:
var a = {
level1:{
level2:{
level3: {
level4: "yolo"
}
}
}
};
deepObjectRemove(a, ["level1", "level2", "level3"]);
console.log(a);
//Prints {level1: {level2: {}}}
#16
8
Try the following method. Assign the Object
property value to undefined
. Then stringify
the object and parse
.
试试下面的方法。将对象属性值赋给undefined。然后对对象进行字符串化并进行解析。
var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};
myObject.regex = undefined;
myObject = JSON.parse(JSON.stringify(myObject));
console.log(myObject);
#17
8
Using ramda#dissoc you will get a new object without the attribute regex
:
使用ramda#dissoc,您将获得一个没有regex属性的新对象:
const newObject = R.dissoc('regex', myObject);
// newObject !== myObject
You can also use other functions to achieve the same effect - omit, pick, ...
您还可以使用其他函数来实现相同的效果——省略、选择、……
#18
7
Using delete method is the best way to do that, as per MDN description, the delete operator removes a property from an object. so you can simply write:
使用delete方法是最好的方法,正如MDN描述的那样,delete操作符从对象中删除属性。所以你可以简单地写:
delete myObject.regex;
// OR
delete myObject['regex'];
The delete operator removes a given property from an object. On successful deletion, it will return true, else false will be returned. However, it is important to consider the following scenarios:
delete操作符从对象中删除给定的属性。如果删除成功,它将返回true,否则将返回false。然而,重要的是考虑以下场景:
If the property which you are trying to delete does not exist, delete will not have any effect and will return true
如果要删除的属性不存在,则delete将没有任何效果,并返回true
If a property with the same name exists on the object's prototype chain, then, after deletion, the object will use the property from the prototype chain (in other words, delete only has an effect on own properties).
如果在对象的原型链上存在同名的属性,那么在删除后,对象将使用来自原型链的属性(换句话说,删除只对自己的属性有影响)。
Any property declared with var cannot be deleted from the global scope or from a function's scope.
不能从全局范围或函数范围中删除使用var声明的任何属性。
As such, delete cannot delete any functions in the global scope (whether this is part from a function definition or a function (expression).
因此,delete不能删除全局范围中的任何函数(无论是函数定义的一部分还是函数(表达式)的一部分)。
Functions which are part of an object (apart from the
global scope) can be deleted with delete.除了全局作用域之外,作为对象一部分的函数可以删除。
Any property declared with let or const cannot be deleted from the scope within which they were defined. Non-configurable properties cannot be removed. This includes properties of built-in objects like Math, Array, Object and properties that are created as non-configurable with methods like Object.defineProperty().
使用let或const声明的任何属性不能从定义它们的范围中删除。无法删除不可配置属性。这包括内置对象的属性,如数学、数组、对象和属性,这些对象都是不可配置的,使用Object. defineproperty()。
The following snippet gives another simple example:
下面的代码片段给出了另一个简单的示例:
var Employee = {
age: 28,
name: 'abc',
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
For more info about and seeing more example, visit the link below:
有关更多信息和更多示例,请访问以下链接:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
#19
3
You can simply delete any property of an object using the delete
keyword.
只需使用delete关键字就可以删除对象的任何属性。
For example:
例如:
var obj = {key1:"val1",key2:"val2",key3:"val3"}
To remove any property, say key1
, use the delete
keyword like this:
要删除任何属性(如key1),请使用delete关键字:
delete obj.key1
Or you can also use array-like notation:
或者你也可以用箭头表示:
delete obj[key1]
Ref: MDN.
裁判:MDN。
#20
3
Dan's assertion that 'delete' is very slow and the benchmark he posted were doubted. So I carried out the test myself in Chrome 59. It does seem that 'delete' is about 30 times slower:
丹的“删除”断言非常缓慢,他发布的基准也受到质疑。所以我自己在Chrome 59进行了测试。似乎“删除”的速度要慢30倍:
var iterationsTotal = 10000000; // 10 million
var 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); // 6135
for (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
Note that I purposedly carried out more than one 'delete' operations in one loop cycle to minimize the effect caused by the other operations.
注意,我特意在一个循环周期中执行了多个“删除”操作,以最小化其他操作带来的影响。
#21
3
Consider creating a new object without the "regex"
property because the original object could always be referenced by other parts of your program. Thus you should avoid manipulating it.
考虑创建一个没有“regex”属性的新对象,因为原始对象总是可以被程序的其他部分引用。因此,您应该避免操纵它。
const myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
const { regex, ...newMyObject } = myObject;
console.log(newMyObject);
#22
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"];
}
}
);
#23
3
Property Removal in JavaScript
There are many different options presented on this page, not because most of the options are wrong—or because the answers are duplicates—but because the appropriate technique depends on the situation you're in and the goals of the tasks you and/or you team are trying to fulfill. To answer you question unequivocally, one needs to know:
在这个页面上有许多不同的选项,不是因为大多数选项是错误的——或者因为答案是重复的——而是因为适当的技术取决于你所处的环境和你和/或你的团队试图完成的任务的目标。要明确地回答你的问题,你需要知道:
- The version of ECMAScript you're targeting
- 你要锁定的ECMAScript版本
- The range of object types you want to remove properties on and the type of property names you need to be able to omit (Strings only? Symbols? Weak references mapped from arbitrary objects? These have all been types of property pointers in JavaScript for years now)
- 想要删除属性的对象类型的范围,以及需要省略的属性名称的类型(仅包含字符串?符号?从任意对象映射的弱引用?这些都是JavaScript中属性指针的类型
- The programming ethos/patterns you and your team use. Do you favor functional approaches and mutation is verboten on your team, or do you employ wild west mutative object-oriented techniques?
- 您和您的团队使用的编程风格/模式。你倾向于功能性的方法,而突变是你的团队中的verboten,或者你是否使用了狂野的西方的突变的面向对象技术?
- Are you looking to achieve this in pure JavaScript or are you willing & able to use a 3rd-party library?
- 您是希望在纯JavaScript中实现这一点,还是您愿意并能够使用第三方库?
Once those four queries have been answered, there are essentially four categories of "property removal" in JavaScript to chose from in order to meet your goals. They are:
一旦回答了这四个查询,在JavaScript中基本上有四种类型的“属性移除”,以满足您的目标。它们是:
Mutative object property deletion, unsafe
This category is for operating on object literals or object instances when you want to retain/continue to use the original reference and aren't using stateless functional principles in your code. An example piece of syntax in this category:
当您希望保留/继续使用原始引用并且在代码中不使用无状态函数原则时,此类别用于对对象文字或对象实例进行操作。这类语法的一个示例:
'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
delete iLikeMutatingStuffDontI[Symbol.for('amICool')] // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
delete iLikeMutatingStuffDontI['amICool'] // throws
This category is the oldest, most straightforward & most widely supported category of property removal. It supports Symbol
& array indexes in addition to strings and works in every version of JavaScript except for the very first release. However, it's mutative which violates some programming principles and has performance implications. It also can result in uncaught exceptions when used on non-configurable properties in strict mode.
这是最古老、最直接和最广泛支持的财产转移类别。除了字符串之外,它还支持符号和数组索引,除了第一个版本外,在每个版本的JavaScript中都可以使用。然而,它是一种突变,它违反了一些编程原则,并且具有性能影响。当在严格模式下使用非可配置属性时,它也会导致未捕获异常。
Rest-based string property omission
This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don't need to account for Symbol keys:
这个类别适用于在普通对象或数组实例上运行的新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 :(
Mutative object property deletion, safe
This category is for operating on object literals or object instances when you want to retain/continue to use the original reference while guarding against exceptions being thrown on unconfigurable properties:
当您想要保留/继续使用原始引用时,该类别是用于对对象文字或对象实例进行操作,同时防止对不可配置属性抛出异常:
'use strict'
const iLikeMutatingStuffDontI = { myNameIs: 'KIDDDDD!', [Symbol.for('amICool')]: true }
Reflect.deleteProperty(iLikeMutatingStuffDontI, Symbol.for('amICool')) // true
Object.defineProperty({ myNameIs: 'KIDDDDD!', 'amICool', { value: true, configurable: false })
Reflect.deleteProperty(iLikeMutatingStuffDontI, 'amICool') // false
In addition, while mutating objects in-place isn't stateless, you can use the functional nature of Reflect.deleteProperty
to do partial application and other functional techniques that aren't possible with delete
statements.
此外,虽然对现有对象进行修改并不是无状态的,但是可以使用reflec . deleteproperty的功能特性来执行部分应用程序和其他一些在delete语句中不可能实现的功能技术。
Syntax-based string property omission
This category is for operating on plain object or array instances in newer ECMAScript flavors when a non-mutative approach is desired and you don't need to account for Symbol keys:
这个类别适用于在普通对象或数组实例上运行的新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 :(
Library-based property omission
This category is generally allows for greater functional flexibility, including accounting for Symbols & omitting more than one property in one statement:
这个类别通常允许更大的功能灵活性,包括在一个语句中忽略多个属性:
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"
#24
2
Try this
试试这个
delete myObject['key'];
#25
2
Hello You Can try this simple an sort
你好,你可以试试这个简单的方法。
var obj = [];
obj.key1 = {name: "John", room: 1234};
obj.key2 = {name: "Jim", room: 1234};
delete(obj.key1);
#26
2
const myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
const { regex, ...other } = myObject;
console.log(myObject)
console.log(regex)
console.log(other)
#27
1
Using lodash
使用lodash
import omit from 'lodash/omit';
const prevObject = {test: false, test2: true};
// Removes test2 key from previous object
const nextObject = omit(prevObject, 'test2');
Using Ramda
使用Ramda
R.omit(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> {b: 2, c: 3}
#28
1
you can use the delete
operator as of below.
您可以使用下面的delete操作符。
var multiverse = {
earth1: "Silver Age",
earth2: "Golden Age"
};
delete multiverse.earth2;//will return true if it finds
// Outputs: { earth1: "Silver Age" }
console.log(multiverse);
The delete operator also has a return value.
If it succeeds in deleting a property, it will return true. If it fails to delete a property because the property is unwritable it will return false
, or if in strict mode it will throw an error.
delete操作符还有一个返回值。如果成功删除属性,则返回true。如果因为属性是不可写的而未能删除属性,它将返回false,或者如果在严格模式下,它将抛出一个错误。
#29
1
@johnstock, we can also use JavaScript's prototyping concept to add method to objects to delete any passed key available in calling object.
@johnstock,我们还可以使用JavaScript的原型概念向对象添加方法来删除调用对象中可用的任何传递键。
Above answers are appreciated.
以上答案都感激。
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
// 1st and direct way
delete myObject.regex; // delete myObject["regex"]
console.log(myObject); // { ircEvent: 'PRIVMSG', method: 'newURI' }
// 2 way - by using the concept of JavaScript's prototyping concept
Object.prototype.removeFromObjectByKey = function(key) {
// If key exists, remove it and return true
if(this[key] !== undefined) {
delete this[key]
return true;
}
// Else return false
return false;
}
var isRemoved =
myObject.removeFromObjectByKey('method')
console.log(myObject) // { ircEvent: 'PRIVMSG' }
// More examples
var obj = { a: 45, b: 56, c: 67}
console.log(obj) // { a: 45, b: 56, c: 67 }
// Remove key 'a' from obj
isRemoved = obj.removeFromObjectByKey('a')
console.log(isRemoved); //true
console.log(obj); // { b: 56, c: 67 }
// Remove key 'd' from obj which doesn't exist
var isRemoved = obj.removeFromObjectByKey('d')
console.log(isRemoved); // false
console.log(obj); // { b: 56, c: 67 }
#30
0
Very simple:
非常简单:
var myObject = {
"ircEvent": "PRIVMSG",
"method": "newURI",
"regex": "^http://.*"
};
delete myObject.regex;