我正在使用 V8 API 创建 JavaScript 对象。其中一些对象通过在 Symbol.iterator
属性中设置 native (拦截)函数来支持迭代。
通过 for...of
迭代这样一个对象工作完美。但是,如果我将它包装在一个空代理中(例如,let x = new Proxy(obj, {});
),生成的对象不可可迭代并抛出一个TypeError
如果尝试对其进行迭代,则显示消息“非法调用”。
包装标准数组不会出现此问题。这是 V8 错误吗?
最佳答案
Wrapping a standard array doesn't exhibit this issue.
是的,就是这样array iterators工作。他们不关心他们正在迭代的对象的种类 - 他们只是访问它的 .length
和索引属性(通常通过代理路由)。
然而,其他标准的奇异对象也表现不佳。如果您尝试在 typed array 上调用 [Symbol .iterator]()
, map或 set包裹在代理中,他们会提示在错误的对象上被调用。
Is this a V8 bug?
不,这是应用程序中的错误。您有三个选择:
- 创建一个迭代器,它不依赖于自定义对象的内部插槽,而是使用它们的公共(public)(代理可拦截)属性接口(interface)。确保您的
[Symbol.iterator]
方法不会对其接收器进行类型检查。 - 检查迭代器方法中的接收器类型,如果它是代理(即具有
[[ProxyTarget]]
内部槽)则使用该值。我强烈建议不要这样做,因为它不符合标准行为并且在绕过处理程序时会破坏代理。 不要使用空代理:
let x = new Proxy(obj, { get(target, key, receiver) { if (key === Symbol.iterator) return target[Symbol.iterator].bind(target); else return Reflect.get(target, key, receiver); } });
关于javascript - V8:ES6 代理在针对自定义对象时不支持迭代协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41046085/