【问题标题】:How are empty cells stored in a sparse array in JavaScript?JavaScript 中的空单元格如何存储在稀疏数组中?
【发布时间】:2012-04-13 18:07:11
【问题描述】:

我有一种情况,我可能设置了一个高索引的数组单元格,而没有设置它之前的任何单元格。

>>> var arr = [];
undefined
>>> arr[5] = 'value';
"filled"
>>> arr
[undefined, undefined, undefined, undefined, undefined, "filled"]

这样的数组是如何存储在内存中的?是否为每个未定义的值分配了空间?

在我的实际项目中,我可能会使用非常大的索引。例如,我可以设置单元格 500-800 和 900-1000。我不能使用哈希,因为我需要遍历这些非空单元格并注意它们的索引。我想知道像这样分割数组是否会为空单元格占用大量内存。

【问题讨论】:

  • 我不确定我是否关注,你为什么不能使用{}?您仍然可以使用 for (i in obj) 循环遍历所有属性。
  • 为什么不能使用哈希表?如果您知道最大索引,您仍然可以使用for 循环。要么元素在哈希表中,你检索并处理它,或者它不在,你继续下一个循环迭代。
  • 如果为每个值分配空间,那么var foo=[]; foo[999999999] = "uh oh"; 将导致大量内存分配。它没有,所以它不是。
  • Are Javascript arrays sparse? 的可能重复项

标签: javascript memory


【解决方案1】:

结合 aefxx 的答案,您仍然可以迭代:

var obj = {500: "foo",  10923: "bar"};
var max = 0;

for (var key in obj)
   max=key>max?key:(max||key);         // get max key

for (var i=0; i<=max; i++)
   console.log(obj[i]);                // output even the undefined

正如 Phrogz 所评论的,它不会为数组的未声明元素分配。如果您将元素值显式设置为未定义(例如arr[somenum] = undefined;),我不确定是否是这种情况

【讨论】:

  • 为了真正看到过去(~500)的日志打印,您必须调整必要的萤火虫设置。我想去 Firefox 地址栏中的about:config 并将extensions.firebug.console.logLimit 设置为至少10950(考虑示例)
【解决方案2】:

我不能使用哈希,因为我需要遍历这些非空单元格并注意它们的索引。

for (x in ...) 语言结构有什么问题?

已编辑以适应 vol7ron 的评论:

var x = {2: "foo", 999: "bar"};

for ( var n in x ) {
    if ( x.hasOwnProperty(n) ) {
        console.log(n);
        console.log(x[n]);
    }
}  

【讨论】:

  • a) 我建议hasOwnProperty is no longer appropriate to use by default。 b)此解决方案的问题是迭代对象的键没有保证顺序,并且根据 OP 的问题,JoJo 似乎可能希望/需要按顺序访问它们。
  • @aefxx:我不知道 Phrogz 写的 defineProperty,尽管我仍然没有 100% 购买它,因为正如他所说,某些浏览器可能存在问题(对我来说,我采用主流浏览器的最低公分母方法 - 自 IE7/FF3 以来)
【解决方案3】:

您可能应该简单地将最大索引存储在一个变量中,然后像这样访问您的地图:

for (var i=0; i<=maxIndex; i++) {
 console.log(myMap[i]);
}

然后您将拥有地图的(相对)紧凑性以及遍历未设置索引的能力。

【讨论】:

    猜你喜欢
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 2018-08-22
    • 2015-09-01
    相关资源
    最近更新 更多