引用ECMA Script 5规范中的Array Objects部分:
如果属性名P
(以字符串形式)是一个数组索引,那么当且仅当ToString(ToUint32(P))
等于P
且ToUint32(P)
不等于232−1时,它就是一个数组索引。
根据上述定义,由于Hello
无效,因此它不被视为数组索引,而只是普通属性。
引用MDN的Relationship between length and numerical properties section部分:
当在JavaScript数组上设置属性时,如果该属性是有效的数组索引并且该索引超出了数组的当前范围,则引擎将相应地更新数组的长度属性
因此,只有当属性是有效的数组索引时,length
属性才会被调整。
在您的情况下,您刚刚在数组对象上创建了一个新属性
Hello
。
注意:在所有的Array原型函数中,只有数值属性会被使用,例如forEach、map等。
例如,在问题中展示的数组,当与forEach一起使用时,
arr.forEach(function(currentItem, index) {
console.log(currentItem, index);
})
将会打印
Hello 0
There 1
123 2
456 3
{ show: [Function] } 4
尽管键列表显示
Hello
。
console.log(Object.keys(arr));
// [ '0', '1', '2', '3', '4', 'Hello' ]
这是因为Array
是从Object
派生而来的。
console.log(arr instanceof Object)
// true
Hello
是一个数组对象中有效的键,但不是有效的数组索引。因此,当您将数组视为对象时,Hello
将包含在键中,但特定于数组的函数将仅包括数字属性。