JavaScript数组大小和未定义的值

4
考虑以下例子:
代码:
var array = [];
array[4] = "Hello World";

结果:

[undefined, undefined, undefined, undefined, "Hello World"]

仅仅声明数组中值所在的位置似乎效率不高。考虑大型数组(100,000+索引)。

在JavaScript中,这实际上是一种低效的使用方式吗?或者说,数组是否以某种方式处理,使得索引并没有被声明为undefined?(即,这只是漂亮的打印来说明空索引吗?)

注意:这个问题的建议重复是错误的。这与零基索引无关。我已经知道数组从0开始!


Wrong representation of JavaScript Array Length 的确切副本。 - Praveen Kumar Purushothaman
@PraveenKumar - 这不是一个重复的问题。我知道索引是从零开始的!- 请查看这个被接受的答案。 - Matthew Layton
你看到第一个答案了吗? - Praveen Kumar Purushothaman
1
@PraveenKumar 我已经看过了,但是你的“完全重复”是一个不同的问题。 - Matthew Layton
3个回答

4
您的猜测是正确的。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

JavaScript数组就是这样工作的。当你声明一个新数组时:

var arr = [];

长度将是0。并且没有元素。
如果在第5个索引处插入:
arr[5] = 10;

然后,JavaScript引擎使用undefined值填充先前的数字索引。从而使数组长度为6而不是1。如果您查看数组内容,它将是:
arr => array(
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    10
)

我已经问了一个关于这个问题的问题,但是我找不到它。问题是:错误表示JavaScript数组长度
从上述问题中复制接受的答案:
“.length”被定义为比最大数值索引的值大1。(它不仅仅是“数值”;它是32位整数值,但基本上是编号属性。)
相反,将“ .length”属性设置为某个数字值(例如,在您的示例中为6)会删除属性,其属性名称为大于或等于您设置的值的数字。

在 Chrome 控制台上检查,var a = []; a[5] = 10; a[2]; // 这里是未定义的。 - fuyushimoya
@fuyushimoya 已经更正了。 - Praveen Kumar Purushothaman

1

这将完全取决于JavaScript解释器如何处理内部结构——这将定义它是否以低效的方式处理。

我的简化假设是,只有在打印数组时才会发现那些未定义的值。基本上意味着只有通过访问才能发现那些特定的索引具有undefined值(即未分配)。 基本上以下内容会有所不同(在我的想法中):

var a = []; a[100] = 1;

to that of:

var a = []; for ( var i=0; i<=99; i++ ) { a[i] = undefined; } a[100] = 1;

后者将会占用所有100个索引的记录空间。而前者只会记录一个索引。
基本上,在定义索引之前,它不会占用存储空间。内部数组结构仅会记录已定义的索引和最大索引。
实际情况可能更加复杂,可以参考v8引擎的概述(无法直接链接到数组部分,因为有人弄乱了锚点ID)。v8引擎似乎有两种存储类型,一种用于处理线性和明确定义的数组,另一种则用于处理我们正在讨论的这种类型(使用哈希),它无法以线性索引方式工作,而是使用“哈希”键位置。

http://www.html5rocks.com/en/tutorials/speed/v8/#toc-topic-numbers


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接