Duktape / C数组元素访问器

时间:2016-05-20 06:20:27

标签: arrays duktape

我正在尝试实现类似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);

我收到一个错误,即length属性不可配置。 有可能实现我想要的吗?一个懒惰的数组'元素绑定?我的印象是,NetSurf设法做到了这一点,但还没有找到解决方法......

1 个答案:

答案 0 :(得分:0)

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

您应该能够使用代理实现您的用例。 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