javascript - V8:ES6 代理在针对自定义对象时不支持迭代协议(protocol)?

标签 javascript proxy ecmascript-6 v8

我正在使用 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]() , mapset包裹在代理中,他们会提示在错误的对象上被调用。

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/

相关文章:

javascript - 将递归 jQuery For every 循环转换为 JavaScript 以进行 VBA 脚本控制

wcf - 直接 channel 使用率还是使用代理?

svn - Cruisecontrol SVN 代理问题

javascript - 从 Observable 中获取 N 个值,直到它基于一个事件完成。延迟加载多选列表

Node.js - 服务器不是构造函数() ES6

javascript - ES6 解构未返回正确结果

javascript jquery ajax 成功返回对象

javascript - 在 Three.js 中为合并的几何体使用多种 Material

javascript - 调用 JSON.parse 时如何处理转义的 unicode 字符?

python - 使用多个代理限制请求