使用SpiderMonkey公共API复制for ... in循环

时间:2012-09-26 11:36:57

标签: javascript for-loop spidermonkey

我正在尝试使用公共C JSAPI探测SpiderMonkey中的一些JavaScript(最新发布版本)。

如何使用公共JSAPI调用复制for...in循环的行为,例如JS_GetPropertyById,JS_LookupProperty,JS_Enumerate等? documentation for JS_Enumerate表示它只返回目标对象上的可枚举属性;它不会在对象的原型链中搜索属性。我想复制for...in循环的确切行为,但避免将代码注入JS环境。看起来JS_NewPropertyIterator可能已被弃用,或者是弃用的强有力候选者。

1 个答案:

答案 0 :(得分:1)

我的第一印象是,这可能不是一件好事。这不是我会做的事情,因为for...in的行为有点怪异和特殊,我不认为这是正确的事情。但如果这真的是你想要的,请继续阅读。

在内部,实际的for...in循环使用js::ValueToIterator,并且该函数似乎没有通过JSAPI公开(至少jsapi.cpp不会在任何地方调用它)。所以你有两个选择:

  1. 说服Mozilla JS团队通过JSAPI公开for...in机制(如果你愿意帮助完成工作,这是可行的);或

  2. 实际上编译一些包含for...in循环的JS代码。

  3. 选项2对您来说会更快。您可以使用此功能,例如:

    function ForInResults(obj) {
        return [v for (v in obj)];
    }
    

    或者如果您更喜欢迭代器:

    function ForInIterator(obj) {
        for (var v in obj)
            yield v;
    }
    

    您可以使用JS_CompileFunction编译其中任何一项功能,然后使用JS_CallFunctionValue进行调用。要从阵列中获取单个元素,请使用JS_GetArrayLengthJS_GetElement。从迭代器中获取值有点棘手,但在循环中添加或删除属性时,它更像是一个真正的for...in循环。