为什么这会返回0长度?

时间:2014-01-11 01:48:54

标签: javascript arrays

在控制台上,我试图创建一个循环数组,我相信如果试图遍历它会导致堆栈溢出,但我甚至无法获得它的长度。

var a = [];
a['b'] = a;

a.length;
// 0

a['c'] = c;
a.length; 
// 0

enter image description here

6 个答案:

答案 0 :(得分:4)

它有length 0因为数组length属性返回的数字高于最高数字索引。

如果您这样做,您将获得length 1

var a = [];
a[0] = a;
a.length; // 1

您可以将带有字符串键的属性分配给数组,它将“起作用”,即数组是对象,可以有额外的属性,但只有数字(整数)索引属性参与数组行为,如.length.slice()。如果要使用字符串键,则应使用普通对象:

var a = {};

(普通)对象没有length(除非你自己创建属性),但你可以使用Object.keys(a).length来获取属性的数量(如果你不关心IE < 9,但没有实现.keys() - 虽然有polyfill)。

答案 1 :(得分:1)

因为您没有向数组添加项目,所以您正在创建对象的属性。

检查a.b

中的内容

答案 2 :(得分:1)

var a = [];
a['b'] = a;

a.length;
// 0

a['c'] = c;
a.length; 
// 0

Javascript中的数组只允许数字作为元素键。

您只需更改密钥即可。

var a = [];
a[0] = a;
a.length == 1

或者使用地图对象而不是数组。

var a = {};
a['b'] = a;
Object.keys(a).length == 1

答案 3 :(得分:0)

JS中的数组被认为是索引数组。即

var arMyArray = [];

创建一个索引数组,可以引用为arMyArray[0], arMyArray[1]等。

对于关联数组,您必须使用对象

var oMyArray = {};

创建一个对象,可以引用为oMyArray['name'] = 'aliasm2k'等。

答案 4 :(得分:0)

您编写的语句a['b'] = a实际上等于a.b = a,这意味着您在a上创建一个名为b的属性,并将其自身分配给新创建的属性b,因此您最终得到一个循环引用: a.b.b.b.b.b.b.b.b...b == a。你可以看看它,它返回true。

我担心您可能错过了数组是可以具有如上所示属性的对象。为了使其行为像数组一样,元素的添加方式就像a[0] = 1一样。因为您在创建的数组上添加了对象属性,而不是作为元素添加,所以数组a为空,这就是a.length为0的原因。

答案 5 :(得分:0)

来自ECMAScript 5.1 Spec

  

数组对象对某类属性进行特殊处理   名。属性名称P(以String值的形式)是一个数组   index 当且仅当ToString(ToUint32(P))等于P和   ToUint32(P)不等于2 ^ 32 - 1

换句话说,数字属性名称被视为数组索引,而非数字属性名称则不是。

此外,

  

length属性的值在数字上大于名称   每个名称为数组索引的属性

这意味着即使我有一个元素,长度也取决于该单个元素的数组索引。具体来说,它总是比最大​​的数组索引大一个。

例如:

var list = [];
list[5] = "Hello World";
console.log(list.length); // Outputs 6!

这也称为稀疏数组。如果您不熟悉JavaScript,那就太奇怪了。