我正在阅读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
我只想了解究竟发生了什么。
答案 0 :(得分:3)
当且仅当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]。
如果一个字符串不是数字,则默认返回对象键。