1

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

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

4

1 回答 1

1

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

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

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

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

选项 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_GetArrayLengthand JS_GetElement。从迭代器中获取值有点棘手,但在循环时添加或删除属性的不寻常情况下,它更像是一个真正for...in的循环。

于 2012-10-02T20:19:19.040 回答