考虑以下示例:
代码:
var array = [];
array[4] = "Hello World";
结果:
[undefined, undefined, undefined, undefined, "Hello World"]
能够只声明数组中您希望值驻留的位置看起来效率很低。考虑大数组(100,000多个索引)。
这实际上是JavaScript中数组的低效使用,还是以 n 索引未实际声明为undefined
的方式处理的数组? (即这只是打印出来以说明空索引吗?)
注意:此问题的建议重复是错误的。这不涉及从零开始的索引。我已经知道数组从0开始了!
答案 0 :(得分:3)
你的假设是正确的。 JS数组是对象和数组声明,如
a = ['a','b','c']
只是
的快捷方式a = {
"0": "a",
"1": "b",
"2": "c"
}
分别a=[]; a[4]='foo'
与
a = {
"4": "foo"
}
您在控制台中看到的一堆undefined
只是控制台转储数组的工件,它们实际上并不存在。
数组和普通对象之间的唯一区别是数组具有“length”属性,该属性以特殊方式处理。 length
始终等于到目前为止分配的最大数字索引加上一个:
a = [];
a[100] = 'x';
a.length; // 101
注意:我正在讨论标准中描述的“理想”JS实现,具体实现可能会以不同的方式提供底层优化和存储阵列。
答案 1 :(得分:1)
JavaScript数组以这种方式工作。声明新数组时:
var arr = [];
长度为0
。而且没有元素。
如果你插入第5个索引:
arr[5] = 10;
然后,JavaScript引擎使用undefined
值填充以前的数字索引。从而使数组长度为6
而不是1
。如果你看到数组内容,那就是:
arr => array(
undefined,
undefined,
undefined,
undefined,
undefined,
10
)
我已经问过这个问题,但是我无法找到它。问题是:Wrong representation of JavaScript Array Length。
从上述问题中复制接受的答案:
.length
被定义为大于最大数字索引的值。 (它不只是&#34;数字&#34 ;;它的32位整数值,但基本上是编号的属性。)相反,将<{1}}属性设置为某个数值(例如,示例中为
.length
)会删除属性名称大于的数字的属性或等于你设定的值。
答案 2 :(得分:1)
完全依赖于JavaScript解释器来确定如何处理内部结构 - 这将定义它是否以低效的方式处理。
我的简化假设是,实际导致打印出阵列是发现这些未定义的唯一点。基本上意味着只有通过访问才能发现那些特定索引的值为undefined
(即未分配)。基本上以下情况会有所不同(在我看来):
var a = []; a[100] = 1;
到:
var a = []; for ( var i=0; i<=99; i++ ) { a[i] = undefined; } a[100] = 1;
后者将占用所有100个索引记录的空间。而前者只记录一个指数。
基本上在定义索引之前,它不会占用存储空间。内部数组结构只记录定义的索引和最大的索引。
我确信现实可能更为复杂,请参阅v8引擎概述(我无法直接链接到Array部分,因为有人弄乱了他们的锚ID;)。似乎v8引擎有两种类型的存储。一个设计用于处理线性和定义良好的数组,另一个用于处理我们正在谈论的类型(通过它使用哈希),它不会以线性索引方式工作,它将使用&#34 ;散列&#34;关键位置。
http://www.html5rocks.com/en/tutorials/speed/v8/#toc-topic-numbers