在控制台上,我试图创建一个循环数组,我相信如果试图遍历它会导致堆栈溢出,但我甚至无法获得它的长度。
var a = [];
a['b'] = a;
a.length;
// 0
a['c'] = c;
a.length;
// 0
答案 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)
数组对象对某类属性进行特殊处理 名。属性名称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,那就太奇怪了。