我可以制作一个"虚拟阵列"在JavaScript?

时间:2014-06-24 21:21:04

标签: javascript arrays virtual

我正在调用一个想要显示一系列内容的JavaScript函数。它显示计数,并逐个显示项目。当我传递一个普通的JavaScript数组时,一切都有效。

但是我有太多的东西要立刻存放在内存中。我想做的是传递一个与数组具有相同接口的对象,并在函数尝试访问数据时调用我的方法。事实上,如果我通过以下内容:

var featureArray = {length: count, 0: func(0)};

然后显示计数,并正确显示第一项。但我不想分配所有条目,否则我将耗尽内存。当用户尝试显示第二个项目时,该功能当前崩溃。我想知道何时访问项目1,并返回项目1的func(1)和项目2的func(2)等(即,延迟创建项目直到请求为止)。

这在JavaScript中是否可行?

4 个答案:

答案 0 :(得分:0)

是的,可以随时随地生成物品。您将需要查看Lazy.js,这是一个用于生成延迟计算/加载序列的库。

但是,您需要更改接受此序列的函数,它需要以与普通数组不同的方式使用。


如果你真的需要伪造一个阵列接口,你可以使用Proxies。不幸的是,它只是一个和谐的草案,目前只有supported in Firefox' Javascript 1.8.5

假设只在迭代中访问数组,即从索引0开始,你可能可以用getter做一些疯狂的事情:

var featureArray = (function(func) {
    var arr = {length: 0};
    function makeGetter(i) {
        arr.length = i+1;
        Object.defineProperty(arr, i, {
            get: function() {
                var val = func(i);
                Object.defineProperty(arr, i, {value:val});
                makeGetter(i+1);
                return val;
            },
            configurable: true,
            enumerable: true
        });
    }
    makeGetter(0);
    return arr;
}(func));

但是,我建议避免这种情况,而是切换期待数组的库。如果使用"数组进行其他任何操作,这个解决方案就会非常错误。但按顺序访问其索引。

答案 1 :(得分:0)

如果我理解正确,这会有所帮助:

var object = {length: count, data: function (whatever) {
    // create your item
}};

然后,您不是array[1]array[2]等,而是object.data(1)object.data(2),等等。

答案 2 :(得分:0)

由于似乎存在一个限制,即必须通过正常数组索引arr[index]使用数组索引来访问数据并且无法更改,因此答案是否,您可以' t覆盖Javascript中的数组索引以更改其工作方式并创建某种仅在需要时获取数据的虚拟阵列。它被提议用于ECMAScript 4并被拒绝作为一个功能。

有关其他讨论/确认,请参阅其他两篇帖子:

How would you overload the [] operator in Javascript

In javascript, can I override the brackets to access characters in a string?

解决此问题的常用方法是切换到使用.get(n)之类的方法来请求数据,然后.get()的实现者可以虚拟化他们想要的内容。


P.S。其他人表示你可以在Firefox中使用Proxy对象(据我所知,在其他浏览器中不支持),但我并不熟悉Proxy对象,因为它的使用似乎而是仅限于目前只针对Firefox的代码。

答案 3 :(得分:0)

感谢所有评论并回答我原始问题的人 - 似乎这不是(目前)JavaScript支持的。

我能够绕过这个限制,仍然按照我的意愿行事。它使用了我在原始问题中没有提到的程序的一个方面(我试图简化问题),所以其他人不能推荐这个是可以理解的。也就是说,它在技术上没有回答我原来的问题,但我会分享它以防其他人认为它有用。

事实证明,每个数组元素中对象的一个​​成员是回调函数。即(使用我原始问题中的术语),func(n)返回一个对象,该对象在一个成员中包含一个函数,该函数由传递数据的方法调用。由于此回调函数知道与之关联的索引(至少在由func(n)创建时),因此它可以在调用时添加数组中的下一个项目(或至少确保它已存在)。更复杂的解决方案可能会提前和/或落后,和/或可能清理不在当前索引附近的项目以释放​​内存。这一切都假设将连续访问这些项目(在我的程序中就是这种情况)。

如,

1)创建一个将保留在范围内的变量(例如,全局变量)。

2)用我在原始问题中给出的对象调用函数:

var featureArray = {length: count, 0: func(0)};

3)func()可以是:

function func(r) {
    return {
        f : function() {featureArray[r + 1] = func(r + 1); DoOtherStuff(r); }
    }
}

假设f()是具有将由外部函数调用的函数的成员。