javascript数组如何存储诸如“;02”;

How does a javascript array store keys such as "02"

本文关键字:存储 数组 何存储 javascript      更新时间:2023-09-26

我在阅读权威指南Javascript时,看到一段话,上面写着,我引用

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

因此,类似a["4"]的东西将存储在索引5处,而类似a["-1.26"]的东西将作为属性"1.26"存储。。

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

这是我的密码。我在node和浏览器上尝试过。

> 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

我只是想了解到底发生了什么。

来自规格

属性名称p(以字符串值的形式)是数组索引,当且仅当ToString(ToUint32(p))等于p,并且ToUint32P不等于2^32-1。

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

因此,"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 );
}

主要要知道的是,您的"数组"实际上更像是一个映射(除了一些例外);

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

如果a是一个数组,这同样适用,只是打印方式可能不同。例如,Google Chrome只会打印数组对象的类数组键(所以在这种情况下,你会看到[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])
}

JavaScript通常会在数组索引设置之前对其运行以下函数:

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

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

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

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