V8:ES6 代理在针对自定义对象时不支持迭代协议?
V8: ES6 proxies don't support iteration protocol when targeting custom objects?
我正在使用 V8 API 创建 JavaScript 对象。其中一些对象通过在 Symbol.iterator
属性.
处设置本机(拦截)函数来支持迭代
通过 for...of
迭代这样的对象非常有效。但是,如果我将它包装在一个空代理中(例如,let x = new Proxy(obj, {});
),生成的对象是 not 可迭代的,并抛出一个 TypeError
和消息 [=23] =] 如果尝试对其进行迭代。
包装标准数组不会出现此问题。这是 V8 错误吗?
Wrapping a standard array doesn't exhibit this issue.
是的,这就是 array iterators 的工作方式。他们不关心他们正在迭代的对象的种类 - 他们只是访问其 .length
和索引属性(通常通过代理路由)。
然而,其他标准的奇异对象也表现不佳。如果您尝试在包装在代理中的 typed array, map or set 上调用 [Symbol.iterator]()
,他们会抱怨在错误的对象上调用。
Is this a V8 bug?
不,这是应用程序中的错误。您有三个选择:
- 创建一个不依赖于自定义对象的内部插槽的迭代器,而是使用它们的 public(代理拦截)属性 接口。确保您的
[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);
}
});
我正在使用 V8 API 创建 JavaScript 对象。其中一些对象通过在 Symbol.iterator
属性.
通过 for...of
迭代这样的对象非常有效。但是,如果我将它包装在一个空代理中(例如,let x = new Proxy(obj, {});
),生成的对象是 not 可迭代的,并抛出一个 TypeError
和消息 [=23] =] 如果尝试对其进行迭代。
包装标准数组不会出现此问题。这是 V8 错误吗?
Wrapping a standard array doesn't exhibit this issue.
是的,这就是 array iterators 的工作方式。他们不关心他们正在迭代的对象的种类 - 他们只是访问其 .length
和索引属性(通常通过代理路由)。
然而,其他标准的奇异对象也表现不佳。如果您尝试在包装在代理中的 typed array, map or set 上调用 [Symbol.iterator]()
,他们会抱怨在错误的对象上调用。
Is this a V8 bug?
不,这是应用程序中的错误。您有三个选择:
- 创建一个不依赖于自定义对象的内部插槽的迭代器,而是使用它们的 public(代理拦截)属性 接口。确保您的
[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); } });