如何从 JavaScript 关联数组中删除对象?

IT技术 javascript arrays associative-array associative
2021-01-24 04:13:19

假设我有这个代码:

var myArray = new Object();
myArray["firstname"] = "Bob";
myArray["lastname"] = "Smith";
myArray["age"] = 25;

现在,如果我想删除“姓氏”?....是否有一些等价物 myArray["lastname"].remove()

(我需要元素消失,因为元素的数量很重要,我想保持干净。)

6个回答

JavaScript 中的对象可以被认为是关联数组,将键(属性)映射到值。

要从 JavaScript 中的对象中删除属性,请使用delete运算符:

const o = { lastName: 'foo' }
o.hasOwnProperty('lastName') // true
delete o['lastName']
o.hasOwnProperty('lastName') // false

请注意,当delete应用于 的索引属性时Array,您将创建一个稀疏填充的数组(即缺少索引的数组)。

在处理 的实例时Array,如果您不想创建一个稀疏填充的数组 - 而您通常不想 - 那么您应该使用Array#spliceor Array#pop

请注意,deleteJavaScript 中运算符不会直接释放内存。它的目的是从对象中删除属性。当然,如果被删除的属性持有对象的唯一剩余引用o,那么o随后将以正常方式进行垃圾回收。

使用delete运算符会影响 JavaScript 引擎优化 代码的能力

@Gottox - lengthArray 对象属性保持不变。
2021-03-22 04:13:19
@johndodo - 是的。这就是为什么我用This will cause questions if used on an Array object instance开始我的初始评论的原因尽管如此,我还是更喜欢在所有情况下都能正确执行的方法,请参阅下面的答案。
2021-03-22 04:13:19
如果在 Array 对象实例上使用以删除现有元素,例如delete myArray[0]. 请参阅stackoverflow.com/a/9973592/426379删除数组元素
2021-03-27 04:13:19
会造成什么问题?
2021-03-31 04:13:19
@Saul:如果真的用作数组出现问题myArray- 但它不是(myArray不幸的名字),它是一个对象。所以在这种情况下delete是可以的。请注意,即使它被创建为new Array()并用作关联数组,它仍然可以。如果您使用的是真正的数组,您的警告仍然需要注意。
2021-04-04 04:13:19

JavaScript 中的所有对象都实现为哈希表/关联数组。因此,以下是等效的:

alert(myObj["SomeProperty"]);
alert(myObj.SomeProperty);

而且,正如已经指出的,delete您可以通过关键字从对象中“删除”一个属性,您可以通过两种方式使用它:

delete myObj["SomeProperty"];
delete myObj.SomeProperty;

希望额外的信息有帮助...

应该注意的是,如果属性不是一个简单的术语,则点符号不起作用。myObj['some;property']工作,但myObj.some;property不会(出于明显的原因)。此外,您可以在括号表示法中使用变量可能并不明显,即var x = 'SomeProperty'; alert(myObj[x])
2021-03-24 04:13:19
@JanDvorak - 嘿,你知道这个答案最初是什么时候写的,是吗?对于大多数用途,这种描述过去和现在都足够了。话虽如此,我理解乏味迂腐。:)
2021-03-30 04:13:19
“JavaScript 中的所有对象都实现为哈希表/关联数组。” - 错误。V8 更喜欢将对象存储为隐藏类 + 密集填充的字段。只有当你对它们做奇怪的事情(例如删除字段)时,它才会放弃并在幕后使用哈希映射。
2021-04-14 04:13:19

之前的答案都没有解决 JavaScript 没有关联数组开始的事实 - 没有这样的array类型,请参阅typeof

JavaScript 拥有的是具有动态属性的对象实例。当属性与 Array 对象实例的元素混淆时,Bad Things™ 必然会发生:

问题

var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log("number of elements: ", elements.length)   // Returns 2
delete elements[1]
console.log("number of elements: ", elements.length)   // Returns 2 (?!)

for (var i = 0; i < elements.length; i++)
{
   // Uh-oh... throws a TypeError when i == 1
   elements[i].onmouseover = function () { window.alert("Over It.")}
   console.log("success at index: ", i)
}

解决方案

要拥有不会对您造成伤害的通用删除功能,请使用:

Object.prototype.removeItem = function (key) {
   if (!this.hasOwnProperty(key))
      return
   if (isNaN(parseInt(key)) || !(this instanceof Array))
      delete this[key]
   else
      this.splice(key, 1)
};

//
// Code sample.
//
var elements = new Array()

elements.push(document.getElementsByTagName("head")[0])
elements.push(document.getElementsByTagName("title")[0])
elements["prop"] = document.getElementsByTagName("body")[0]

console.log(elements.length)                        // Returns 2
elements.removeItem("prop")
elements.removeItem(0)
console.log(elements.hasOwnProperty("prop"))        // Returns false as it should
console.log(elements.length)                        // returns 1 as it should
@johndodo - ArrayJS 中的所有s 都是对象,尝试typeof new Array();typeof []验证。Array只是某种物体,根本不是“不同的野兽”。在 JS 中,对象通过它们的构造函数名称和原型链来区分,参见基于原型的编程
2021-03-22 04:13:19
delete没有不足。delete旨在删除属性。而已。将删除运算符应用于数组的索引会删除该索引。还需要做什么?你只剩下一个稀疏数组,这是该语言的一个特性。如果您不想要稀疏数组,请不要删除索引:使用splicepop
2021-03-23 04:13:19
@johndodo - 你具体指的是什么问题?上面代码的目的是通过提供一个简单的多态函数delete来解决算子的不足Array
2021-03-24 04:13:19
你没有抓住重点。我知道数组也是对象,但这并不意味着这样使用它们是明智的。程序员应该决定他是想将某些东西用作数组(使用 push、pop、[]、...)还是用作对象/“关联数组”。混合搭配不是一个好方法,正是因为您的解决方案试图隐藏问题。如果您事先决定使用哪种设计模式(数组或对象),就不会有这样的问题。
2021-04-03 04:13:19
这个解决方案有两个问题:它隐藏了一个事实,即数组和对象在 JS 中是完全不同的野兽(你知道,但显然 OP 没有)并且它使用原型。如果他了解数组和对象(并相应地命名他的变量),OP 会更好——试图隐藏两者之间的差异只会给他带来更多麻烦。恕我直言,当然。
2021-04-06 04:13:19

这只会删除对象,但它仍然保持数组长度不变。

要从数组中删除元素,您需要执行以下操作:

array.splice(index, 1);
@Andreaa Panagiotidis 除非我们不谈论数组,在这种情况下,它 100% 的时间都是错误的 🙂
2021-04-03 04:13:19
确实,但在这种情况下没有使用数组,只是一个普通的旧对象,因此它没有 length 或 splice 方法。
2021-04-04 04:13:19

虽然接受的答案是正确的,但它没有解释它为什么起作用。

首先,您的代码应该反映这不是数组的事实

var myObject = new Object();
myObject["firstname"] = "Bob";
myObject["lastname"] = "Smith";
myObject["age"] = 25;

请注意,所有对象(包括Arrays)都可以这样使用。但是,不要指望标准的 JavaScript 数组函数(pop、push 等)可以处理对象!

正如在接受的答案中所说,然后您可以使用delete从对象中删除条目:

delete myObject["lastname"]

你应该决定你想走哪条路——要么使用对象(关联数组/字典),要么使用数组(地图)。切勿将两者混用。

很好的答案。我只会建议任何阅读本文的人都不应将 javascript 中的数组抽象为“地图”,而应将其抽象为“列表”。那是因为在使用数组时你不应该试图控制元素的索引。如果你尝试......好吧,只是不要:D
2021-04-07 04:13:19