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属性,以及附加的一些方法(如sortpopjoin等)。 事实上, 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“索引”。