在javascript中删除运算符

时间:2014-07-04 08:23:55

标签: javascript ecmascript-5

本书Javascript:权威指南在第6章的第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中尝试上面的代码片段时, 数组的长度仍然是3。<​​/ p>

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

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

1 个答案:

答案 0 :(得分:4)

根据MDN

  

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

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

  • 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

§11.4.1中描述了

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

在我看来(但这只是猜测)混淆来自§15.4.5.2,他们说:

  

此Array对象的length属性是一个data属性,其值始终在数值上大于名称为数组索引的每个deletable属性的名称。

根据这个单句,然后删除数组的最后一个元素也可以减少其长度。此行为不符合§15.4.5.1,标准只表明length 大于...数组索引,而不是最高指数+ 1。

总结一下简单的说法:delete运算符只需删除成员,但length不受影响。