本书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规范中是否有一个规范说删除应删除元素,浏览器决定不根据该脚本实现。或者这本书错了..?
答案 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
不受影响。