如何从JavaScript对象中移除一个属性?

假设我创建一个对象如下:

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

如何删除财产regex以最终结束新的最佳方式myObject如下?

var myObject = {
    "ircEvent": "PRIVMSG",
    "method": "newURI"
};

喜欢这个:

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

演示

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

console.log(myObject);

操作员delete出乎意料地很慢!

看看基准

删除是删除对象的属性没有任何剩菜剩下的唯一真正的方法,但它的工作比其“替代”设置慢100倍object[key] = undefined

这个选择不是这个问题的正确答案!但是,如果你小心使用它,你可以大大加快一些算法。如果您delete在循环中使用并且在性能方面存在问题,请阅读详细解释。

什么时候应该使用delete什么时候设置值undefined

一个对象可能被看作是一组键值对。我称之为’价值’是一个原始的或对其他对象的引用,连接到’钥匙’。

使用delete当你路过结果对象的代码上,你就不用管了(或者当你不知道你的团队或自己)。

从哈希映射中删除密钥

 var obj = {
     field: 1     
 };
 delete obj.field;

使用设置undefined当你关心性能。它可以大大提高你的代码。

其在HashMap中的地方重点遗体,只有值被替换undefined。理解,该for..in循环仍然会遍历该密钥。

 var obj = {
     field: 1     
 };
 obj.field = undefined;

使用这种方法,并不是所有确定财产存在的方式都能按预期工作。

但是,这个代码:

object.field === undefined

对于这两种方法将表现等效。

测试

总而言之,不同之处在于确定财产存在的方式以及关于for..in循环。

 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 :)

 var counter = 0,
     key;
 for (key in obj) {
     counter++;
 }
 console.assert(counter === 0, 'counter === 0', '"field" is not iterated using "for .. in" loop. *');

正如其他人所说,你可以使用delete。但JavaScript是一种OOP语言,所以一切都是一个对象。因此,我觉得有必要指出一个特别的警告。

在数组中,与普通的旧对象不同,使用delete在表单中留下垃圾,null在数组中创建一个“洞”。

var array = [1, 2, 3, 4];
delete array[2];
/* Expected result --> [1, 2, 4]
 * Actual result   --> [1, 2, null, 4]
 */

正如你所看到的,delete并不总是像人们所期望的那样工作。该值被覆盖,但内存不会被重新分配。

忽视固有的危险和问题null以及浪费的空间,如果阵列需要精确,这可能会产生问题。

例如,假设您正在创建一个使用JSON序列化的web应用程序将用于“选项卡”的数组存储在字符串中(在这种情况下localStorage)。我们还要说,代码使用数组成员的数字索引在画到屏幕时“标题”它们。你为什么要这样做,而不是只存储“标题”?因为…… 原因

好吧,让我们只想说,你想在这个请求节省内存一个谁运行,从1960年的运行UNIX的PDP-11小型机的用户,并写了他自己Elinks为基础,JavaScript的标准,行式打印机友好浏览器,因为X11是不可能

除了边缘情况越来越愚蠢的情况外,delete在所述数组上使用将导致null数组污染,并可能在后来导致应用程序中的错误。如果你检查null,它会直接跳过数字导致标签呈现像[1] [2] [4] [5] ...

if (array[index] == null)
    continue;
else
    title = (index + 1).toString();
/* 0 -> "1"
 * 1 -> "2"
 * 2 -> (nothing)
 * 3 -> "4"
 */

是的,那绝对不是你想要的。

现在,您可以保留第二个迭代器,例如j只在从数组中读取有效值时才增加。但是这并不能完全解决null问题,你还是得请那个troll PDP-11用户。唉,他的电脑没有足够的内存来保存最后一个整数(不要问他如何设法处理可变宽度的数组……)

所以,他愤怒地发给你一封电子邮件:

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

大约现在,你在智慧的结尾。这家伙一直在不停地抱怨你的应用,并且你想告诉他闭嘴,去找一台更好的电脑。

幸运的是,数组确实有删除索​​引和重新分配内存的特殊方法:Array.prototype.splice()。你可以写这样的东西:

Array.prototype.remove = function(index){
  this.splice(index,1);
}
...
array = [1, 2, 3, 4];
array.remove(2);
// Result -> [1, 2, 4]

就这样,你对PDP-11先生感到高兴。万岁!(尽管……我仍然告诉他)

添加评论

友情链接:蝴蝶教程