1

我正在尝试实现类似于 HTMLCollection 的东西,它是一个可以在没有 JS 操作的情况下丢失/获得元素的数组。

duk_push_object(ctx);
duk_push_string(ctx, "length");
duk_push_c_function(ctx, my_length_getter, 1);
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER);
duk_push_c_function(ctx, my_item_getter, 1);
duk_put_prop_string(ctx, -2, "item");

像上面那样做,我得到一个对象,我可以在该对象上读取 my_array.length 属性并通过调用方法 my_array.item(index) 获取一个项目。但是我没有通过使用 my_array[index] 得到一个项目。如果我将上面的第一行替换为

duk_push_array(ctx);

我收到一个错误,即长度属性不可配置。有没有可能实现我想要的?具有“惰性”元素绑定的数组?我的印象是 NetSurf 以某种方式设法做到了这一点,但还没有完全弄清楚如何......

4

1 回答 1

0

Ecmascript 为属性虚拟化提供了两种主要的标准机制:getter/setter(访问器)和代理对象。Getter/setter 仅限于您事先明确设置的属性,因此它们并不总是适用于完全虚拟化对象,但代理对象可以捕获所有属性读取和写入等内容。

您应该能够使用代理来实现您的用例。Duktape 实现了代理陷阱的一个子集(记录在http://duktape.org/guide.html#es6-proxy中)。作为捕获所有属性读取和写入(但将它们转发到目标)的最小示例:

var target = { foo: 'hello' };
var proxy = new Proxy(target, {
    get: function (targ, key) {
        print('get', key);
        // may also return a virtualized value
        return targ[key];
    },
    set: function (targ, key, val) {
        print('set', key, val);
        // may also capture (virtualize) write, or reject write
        targ[key] = val;
        return true;  // indicate write was allowed
    }
});
print(proxy.foo);
proxy.bar = 123;

使用“duk”运行打印:

get foo
hello
set bar 123
于 2016-05-21T23:16:11.297 回答