【问题标题】:delete operator in javascript [duplicate]javascript中的删除运算符[重复]
【发布时间】:2014-08-25 12:39:48
【问题描述】:

这本书 Javascript:权威指南在第 6 版的章节中陈述了以下内容

4.13.3 删除操作符

var a = [1,2,3]; // Start with an array
delete a[2]; // Delete the last element of the array
a.length // => 2: array only has two elements now

但是当我在 Firefox 和 chrome 中尝试上述 sn-p 时, 数组的长度仍然是 3。

这是来自书中的错误信息,还是浏览器中 javascript 的实现与 javascript 规范不同?

注意: 我尝试了splice 并删除了该元素。我怀疑 ecmascript 规范中是否有一个规范说 delete 应该删除元素并且浏览器决定不根据该脚本实现。还是书错了..?

【问题讨论】:

标签: javascript ecmascript-5


【解决方案1】:

根据MDN

删除数组元素时,数组长度不受影响。即使您删除了数组的最后一个元素,这仍然成立。

那么你的最后一个假设是错误的(“数组现在只有两个元素”)。正如 RobG 在 cmets 中指出的那样,这是错误的,原因有两个:

  • Array.length 是数组的长度(参见后面引用的最后一个 §15.4.5.2),而不是它包含的元素数。
  • 在您的情况下,a.length 不是两个而是三个,因为delete 不会修剪数组。

这是什么意思?那条评论是对的(a 有两个元素)但代码是错误的(数组长度仍然是三个)。

当你从数组中删除一个元素时,你得到的是undefined 而不是那个元素(当你尝试访问那个索引时):

var a = [1,2,3]; // a == [1, 2, 3]
delete a[2]; // a == [1, 2, undefined]

来自ECMAScript Language Specification

delete 运算符在 §11.4.1 中进行了描述。它说[[Delete]] 数组内部方法将被调用。现在我们知道(来自§8.6.2)我们应该检查[[DefineOwnProperty]] 数组内部方法,因为仅仅删除索引属性是不够的。从 §15.4.5.1 我们可以看到 length 属性可以更改为 truncate array 但它不会影响删除(删除)一个数组项,因为它不会做任何赋值(然后§15.4.5.1 将不适用)。你会得到undefined,因为现在没有这样的成员,根据§8.6.1结果是undefined

在我看来(但这只是推测)混淆源于 §15.4.5.2 他们说:

此 Array 对象的长度属性是一个数据属性,其值在数值上始终大于名称为数组索引的每个可删除属性的名称。

根据这句话,删除数组的最后一个元素可能也会减少它的长度。这种行为不符合 §15.4.5.1 并且标准只是声明length 大于...数组索引,而不是最高索引 + 1。

简而言之:delete 运算符只是删除一个成员,但length 不受影响。

【讨论】:

  • 感谢答案 :) 我发现执行代码时会发生什么。但是让我烦恼的是,为什么这本书说长度为 2。所以我的问题是,chrome 或 firefox 的 javascript 实现是否偏离了 ecmascript 规范,该规范说 delete 应该从数组中删除元素。 .?有这样的规范吗?
  • 不,他们的实现是正确的(我不知道你在看哪本书),让我搜索参考。
  • JavaScript: The Definitive Guide 6th edition by David Flanagan,第 4.13.3 章删除运算符,第 84 页
  • "When you delete an element from an array what you get is to replace that element with undefined"。不,该属性被完全删除,你得到的是[1,2]但长度仍然是3,试试a.hasOwnProperty('2')。尝试访问不存在的成员会返回 undefined。
  • Then to be wrong is your last assumption ("array only has two elements now")。这个“假设”是绝对正确的,数组只有两个元素。
猜你喜欢
  • 1970-01-01
  • 2016-05-25
  • 2011-03-09
  • 1970-01-01
  • 2017-04-05
  • 2013-05-24
  • 2011-07-28
  • 2015-06-13
  • 2015-03-16
相关资源
最近更新 更多