V8:ES6代理在定位自定义对象时不支持迭代协议?

时间:2016-12-08 18:09:51

标签: javascript proxy ecmascript-6 v8

我使用V8 API创建JavaScript对象。其中一些对象通过在Symbol.iterator属性上设置本机(截获)函数来支持迭代。

通过for...of迭代这样的对象非常有效。但是,如果我将它包装在空代理中(例如,let x = new Proxy(obj, {});),则生成的对象可迭代并抛出TypeError消息"非法调用& #34;如果试图迭代它。

包装标准阵列并不会出现此问题。这是V8的错误吗?

1 个答案:

答案 0 :(得分:6)

  

包装标准阵列不会出现此问题。

是的,这就是array iterators的工作方式。他们不关心他们迭代的对象的类型 - 他们只是访问它的.length和索引属性(通常通过代理路由)。

然而,其他标准的异国情调对象也表现不佳。如果您尝试在代理中包含的typed arraymapset上调用[Symbol​.iterator](),他们会对在错误的对象上调用而烦恼。

  

这是V8错误吗?

不,这是应用程序中的一个错误。你有三个选择:

  • 创建一个不依赖于自定义对象的内部插槽的迭代器,而是使用其公共(代理可拦截)属性接口。确保您的[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);
        }
    });