如果我在数组中只设置一个高索引,是否会浪费内存?

Nic*_*ick 40 javascript memory arrays

在Javascript中,如果我做了类似的事情

var alpha = [];
alpha[1000000] = 2;
Run Code Online (Sandbox Code Playgroud)

这会浪费内存吗?我记得读过一些关于Javascript数组仍然为未指定的索引设置值的东西(可能将它们设置为未定义?),但我认为这可能与删除有关.我真的不记得了.

pat*_*ros 25

请参阅此主题: are-javascript-arrays-sparse

在Javascript的大多数实现中(可能是所有现代的)数组都是稀疏的.这意味着不,它不会将内存分配到最大索引.

如果它像Lua实现那么实际上有一个内部数组和字典.来自起始索引的密集部分将存储在数组中,字典中的稀疏部分.


CMS*_*CMS 23

这是一个古老的神话.不会分配阵列上的其他索引.

当您指定属性名称为"数组索引"(例如alpha[10] = 'foo',表示无符号32位整数的名称)并且它大于对象length属性的当前值时Array,将发生以下两件事:

  1. 将在对象上创建"index named"属性.
  2. length将递增到是index + 1.

概念证明:

var alpha = [];
alpha[10] = 2;
alpha.hasOwnProperty(0);  // false, the property doesn't exist
alpha.hasOwnProperty(9);  // false
alpha.hasOwnProperty(10); // true, the property exist
alpha.length;             // 11
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,hasOwnProperty方法返回false时,我们测试存在的的0还是9性能,因为他们没有在对象上实际存在,而它返回true10,财产被创建.

这种误解可能来自流行JS控制台,像萤火虫,因为当它们检测到被物体印刷阵列状之一,他们会简单地使一个循环,表示从各索引值的0length - 1.

例如,萤火虫检测阵列状物体单单看他们是否有一个length其它的值是一个无符号的32位整数属性(小于2 ^ 32 - 1),并且如果它们具有一个splice属性,该属性是一个函数:

console.log({length:3, splice:function(){}});
// Firebug will log: `[undefined, undefined, undefined]`
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,Firebug将在内部进行一个顺序循环,以显示每个属性值,但是没有任何一个索引真正存在并且显示[undefined, undefined, undefined]会给你错觉这些属性存在,或者它们被"分配",但事实并非如此......

这就像以前一样,甚至是ECMAScript第1版规范(截至1997年),你不应该担心实现差异.

  • 这更多是对数组的 __logical__ 行为的描述,而不是对数组运行时性能的指导。我在规范中没有看到任何将内存或 CPU 消耗限制到任何特定模型的内容(并不是我对规范的阅读是确定的。) (2认同)