javascript数组如何存储键,例如" 02"

时间:2013-08-11 17:30:46

标签: javascript node.js

我正在阅读Javascript,这是权威的指南,并且遇到了一个段落,并且我引用了

  

如果使用恰好非负数的字符串索引数组   整数,它表现为数组索引而不是对象属性

因此a["4"]之类的内容将存储在索引5处,而a["-1.26"]之类的内容将存储为属性"1.26" ..

我有点冒险并试过a["02"] = 2; 现在我可以设置它,检索它但它既没有设置为a[2](基本上是a[parseInt("02")]),也不能在打印数组时得到它。

这是我的代码。我尝试了节点和浏览器。

> a[3] = 3;
3
> a["-1.2"] = 10;
10
> a
[ , , , 3, '-1.2': 10 ]
> a["02"] = 2;
2
> a
[ , , , 3, '-1.2': 10 ]
> a["02"]
2
> a.length
4

我只想了解究竟发生了什么。

3 个答案:

答案 0 :(得分:3)

From specs

  

当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于2 ^ 32-1时,属性名P(以String值的形式)是数组索引。

所以这本书有误导性,因为它需要是一个整数,没有前导零等。

所以"02"被视为"hellokitty" - 在任何意义上都不是索引属性。

考虑一下:

var P = "02"
console.log( ( P ) === ( ( +P >>> 0 ).toString() ) );
//false

var P = "2"
console.log( ( P ) === ( ( +P >>> 0 ).toString() ) );
//true

这是一个功能

function isStringConsideredArrayIndex( P ) {
    if( typeof P !== "string" ) throw new Error( "strings only" );
    return ( (P >>> 0).toString() ) === P && 
        ( P >>> 0 ) !== ( Math.pow( 2, 32 ) - 1 );
}

答案 1 :(得分:1)

要知道的主要事实是你的“数组”实际上更像是一张地图(有一些例外);

a = {}; // a is an empty object
a['02'] = 'foo';
a['2'] = 'bar';
console.log( a ); // { '02': 'foo', '2': 'bar' }

如果a是一个数组,则同样适用,除​​了它的打印方式可能不同。例如,谷歌浏览器只会打印数组对象的类似数组的键(所以在这种情况下你会看到[undefined, undefined, 'bar']。它仍然有其他属性,但它的“打印功能”因为缺少更好的术语只显示类似数组的那些。

还有其他差异。数组具有某些属性,例如length(它将等于您定义的最大数字索引+ 1),以及各种操作函数('pop','join'等)。

正如已经指出的那样,如果索引可以无损地转换为无符号整数,则它被认为是类似数字的。即"2" -> 2 -> "2"没有任何损失,而"02" -> 2 -> "2"失去领先的0

要查看对象或数组中所有内容的完整列表,您可以使用此列表(将显示您缺少的“02”键):

for(var i in a){
    console.log(i,a[i])
}

答案 2 :(得分:0)

在内部,JavaScript将在数组索引设置之前运行以下函数:

    function ToUint32(x) {
        return x >>> 0;
    }

因此,只有作为数字的数字或字符串才是有效的数组索引。

索引也必须在以下范围[0,2 ^ 32-1]。

如果一个字符串不是数字,则默认返回对象键。