JavaScript数组:string索引的项目
我最近对JavaScript数组索引的性质有了一点警觉。 追求它,我发现以下(我在这里解释模式下使用Node.js ):
var x=[]; x['a']='a'; console.log(x); // Yields [ a: 'a' ] console.log(x.length); // yields 0 not 1 x[1]=1; console.log(x); // Yields [ , 1, a: 'a' ] console.log(x.length); // Yields 2 not 3 (one for empty 0 space, one for the occupied 1 space)
是a: 'a'
真的看起来像一个embedded在数组中的对象属性,因此不计入数组属性.length
。
在JavaScript中,数组只是具有一些特殊属性的对象,如自动length
属性,以及附加的一些方法(如sort
, pop
, join
等)。 事实上, a
数不会被计入你的数组中,因为一个数组的length
属性只存储了可以用一个32位正整数表示的属性名称的数量 。
而且,由于数组总是自动定义每个编号的元素,直到具有正32位整数属性名称的最高元素,这实际上意味着length
属性存储1高于具有最高32位整数的元素作为属性名称 。 感谢@ Felix Kling在评论中纠正了我的这个问题。
添加诸如a
属性是完全不被禁止的,但是你应该小心,因为在阅读你的代码时可能会引起混淆。
在数组中遍历元素也有所不同:
走过所有编号的元素:
for (var i=0; i<myArray.length; i++) { //do something }
浏览所有非内置的财产:
for (var i in myArray) { //do something }
请注意,此循环还将包含Array.prototype
中包含的任何不是内置方法的内容。 所以,如果你要添加Array.prototype.sum = function() {/*...*/};
,它也将被循环。
要找出你使用的对象是否是一个数组,而不仅仅是一个对象,你可以执行下面的testing:
if (Object.prototype.toString.call(myObject) === '[object Array]') { //myObject is an array } else if (typeof myObject === 'object') { //myObject is some other kind of object }
请参阅@ artem的评论 : myObject instanceof Array
可能无法正常工作。
这是正确的,这是一个很好的例证,你创build的新数组实际上只是一种特殊的对象。 实际上, typeof []
是'object'
! 设置一个命名的属性(这可能是写得更干净,因为xa = 'a'
)真的是设置一个新的属性到你的“真正的”数组(真正的编号属性)的对象包装。 它们不会影响length属性,这与Array.isArray
方法不相同。
对,那是正确的。 这是可行的,因为JavaScript中几乎所有东西都是一个对象,包括数组和函数,这意味着您可以添加自己的任意string属性。 那不是说你应该这样做。
数组( []
)应该使用非负整数进行索引。 对象( {}
)应该使用string“索引”。