以数字作为属性名的Javascript数组

以数字作为属性名的Javascript数组,javascript,arrays,Javascript,Arrays,为什么上面的示例中length113?'112'是否应该为数组添加对象属性并创建类似于myArray={“112”:0} 除此之外,为什么长度是113而不是1?由于myArray实际上只包含一个值数组长度比最高索引多一个,因此,您得到了113您得到了0..112元素的数组-总共113个元素。不。'112'字符串和纯数字112在JS执行数组查找时的计算结果是相同的,因此您在数组中得到的是一个槽,而不是一个属性 将JS数组索引视为恰好是数字的属性最简单,即使是字符串形式。它比你一开始想象的更像变色龙

为什么上面的示例中
length
113?
'112'
是否应该为数组添加对象属性并创建类似于
myArray={“112”:0}


除此之外,为什么长度是113而不是1?由于
myArray
实际上只包含一个值

数组
长度
比最高索引多一个,因此,您得到了
113

您得到了
0..112
元素的数组-总共113个元素。

不。
'112'
字符串和纯数字
112
在JS执行数组查找时的计算结果是相同的,因此您在数组中得到的是一个槽,而不是一个属性

将JS数组索引视为恰好是数字的属性最简单,即使是字符串形式。它比你一开始想象的更像变色龙


但是,如果您添加了一个具有非数字名称的属性,例如
myArray['foo']
,它将按照您的预期执行,并且长度不会更改。

考虑以下简单示例:

var myArray = new Array(); 
myArray['112'] = 0;
myArray.length
数字3用于指定属性名称,但它被转换为字符串并用作标准属性名称(即字符串“3”)

添加名为“3”的属性会创建一个属性,并将长度设置为4,因为长度总是比最大的非负整数属性名称多设置一个


没有创建其他属性,数组是“稀疏”的,即它没有顺序命名(编号)的成员。for..in循环也可以用来查看只有一个属性。

pshhh….这很令人惊讶。每天学习新知识。因为长度总是设置为最大的正整数属性名加上一。数组只有一个可枚举属性,但它的长度为113(请参阅ECMA-262 15.4)。它可能是内部的,具体取决于存储的值。@MatthewFlaschen:是的,对不起,我刚去了忍者编辑,但似乎有人已经注意到:如果你给它们按顺序编号的索引,PArrays只有按顺序编号的索引。OP的例子是它们不是连续的。数组只有一个名为“112”的可枚举属性。长度自动设置为最大的正整数属性名加上一(因此设置为'113')。@RobG:我明白了。为什么
console.log()?我看到
Object.keys()
显示了唯一的可枚举属性。如果答案是错误的,我会对它做什么修改?从第一句中删除“sequential”和短语“and is sparse”(sparse是索引不是顺序的概念,因此它可能是实例的属性,而不是数组的一般属性)。完全删除第二句话,特定索引的分配不会导致所有较低的索引都被创建为属性(至于..,在迭代中将显示)。尝试访问缺少的属性将返回undefined,hasOwnProperty将返回false(尽管在某些浏览器中,尝试访问缺少的索引会导致它们被添加为属性,但它们仍然未定义)。“数组中的插槽”是一个属性。所有数组属性名称都是字符串,即使在赋值中使用了数字(它被转换为字符串)。数组只是具有特殊长度属性的对象。长度始终比最大的正整数属性名大一个。您可以将其向后设置。听起来很疯狂,根据ECMAScript规范,所有数组索引实际上都是字符串属性,而不是数字索引
aa[1]=“一”被解释器转换为
var aa={0':'zero',1':'one'}
,但请记住,数组继承自Array.prototype,并具有特殊的长度属性,因此它们比普通对象复杂一些。但在下面,它们只是物体。哦,转换为字符串的数字属性名是对象工作方式的一部分,也适用于数组,它不是特定于数组的。
var aa = [];
aa[3] = 'three';
alert( aa.length // 4
  + '\n' + aa[2]    // undefined 
  + '\n' + aa.hasOwnProperty('2') // false
);