也就是说,如果我使用当前时间作为数组的索引:
array[Date.getTime()] = value;
解释器会实例化从 0 到现在的所有元素吗?不同的浏览器有不同的做法吗?
我记得曾经在AIX内核中有一个错误,它会根据请求创建伪 tty,但是如果你这样做了,比如“echo > /dev/pty10000000000”,它会创建 /dev/pty0、/dev/pty1, ....然后摔倒死了。在贸易展上很有趣,但我不希望这发生在我的客户身上。
也就是说,如果我使用当前时间作为数组的索引:
array[Date.getTime()] = value;
解释器会实例化从 0 到现在的所有元素吗?不同的浏览器有不同的做法吗?
我记得曾经在AIX内核中有一个错误,它会根据请求创建伪 tty,但是如果你这样做了,比如“echo > /dev/pty10000000000”,它会创建 /dev/pty0、/dev/pty1, ....然后摔倒死了。在贸易展上很有趣,但我不希望这发生在我的客户身上。
对,他们是。它们实际上是内部的哈希表,因此您不仅可以使用大整数,还可以使用字符串、浮点数或其他对象。toString()
在添加到哈希之前,所有键都通过转换为字符串。您可以使用一些测试代码来确认这一点:
<script>
var array = [];
array[0] = "zero";
array[new Date().getTime()] = "now";
array[3.14] = "pi";
for (var i in array) {
alert("array["+i+"] = " + array[i] + ", typeof("+i+") == " + typeof(i));
}
</script>
显示:
array[0] = zero, typeof(0) == string
array[1254503972355] = now, typeof(1254503972355) == string
array[3.14] = pi, typeof(3.14) == string
请注意我如何使用for...in
语法,它只为您提供实际定义的索引。如果您使用更常见for (var i = 0; i < array.length; ++i)
的迭代方式,那么您显然会遇到非标准数组索引的问题。
JavaScript 数组的具体实现方式因浏览器而异,但它们通常会回退到稀疏实现 - 很可能与用于常规对象的属性访问相同的实现 - 如果使用实际数组效率低下。
您必须询问对特定实现有更多了解的人来回答是什么触发了从密集到稀疏的转变,但您的示例应该是完全安全的。如果你想得到一个密集数组,你应该用一个显式的长度参数调用构造函数,并希望你能真正得到一个。
有关olliej 的更详细描述,请参阅此答案。
您可以通过使用专为此类事情设计的 javascript 语法来避免该问题。你可以把它当作一本字典,但是“for ... in ...”语法会让你把它们全部抓起来。
var sparse = {}; // not []
sparse["whatever"] = "something";
Javascript 对象是稀疏的,数组只是具有自动维护的长度属性(实际上比最大索引大 1,而不是定义元素的数量)和一些附加方法的专用对象。无论哪种方式,您都是安全的;如果您需要它的额外功能,请使用数组,否则使用对象。
与 JavaScript 一样,答案通常是“它有点奇怪……”
内存使用没有定义,任何实现都是愚蠢的。理论上,const a = []; a[1000000]=0;
可以像const a = [];
. 在实践中,即使是微软也避免了这些实现。
Justin Love指出,length 属性是最高索引集。但只有在索引是整数时才更新。
所以,数组是稀疏的。但是像reduce()、Math.max()和“for ... of”这样的内置函数将遍历从0到长度的整个可能整数索引范围,访问许多返回'undefined'的函数。但是 'for ... in' 循环可能会如您所愿,只访问定义的键。
下面是一个使用 Node.js 的例子:
"use strict";
const print = console.log;
let a = [0, 10];
// a[2] and a[3] skipped
a[4] = 40;
a[5] = undefined; // which counts towards setting the length
a[31.4] = 'ten pi'; // doesn't count towards setting the length
a['pi'] = 3.14;
print(`a.length= :${a.length}:, a = :${a}:`);
print(`Math.max(...a) = :${Math.max(a)}: because of 'undefined values'`);
for (let v of a) print(`v of a; v=:${v}:`);
for (let i in a) print(`i in a; i=:${i}: a[i]=${a[i]}`);
给予:
a.length= :6:, a = :0,10,,,40,:
Math.max(...a) = :NaN: because of 'undefined values'
v of a; v=:0:
v of a; v=:10:
v of a; v=:undefined:
v of a; v=:undefined:
v of a; v=:40:
v of a; v=:undefined:
i in a; i=:0: a[i]=0
i in a; i=:1: a[i]=10
i in a; i=:4: a[i]=40
i in a; i=:5: a[i]=undefined
i in a; i=:31.4: a[i]=ten pi
i in a; i=:pi: a[i]=3.14
但。还有更多关于 Arrays 的极端情况尚未提及。