I'm using the V8 API to create JavaScript objects. Some of these objects support iteration by setting up a native (intercepted) function at the Symbol.iterator
property.
Iterating such an object via for...of
works perfectly. However, if I wrap it in a null proxy (e.g., let x = new Proxy(obj, {});
), the resulting object is not iterable and throws a TypeError
with the message "Illegal invocation" if an attempt is made to iterate over it.
Wrapping a standard array doesn't exhibit this issue. Is this a V8 bug?
Wrapping a standard array doesn't exhibit this issue.
Yes, that's how array iterators work. They don't care about the kind of the object they are iterating - they simply access its .length
and indexed properties (which are routed normally through the proxy).
However, other standard exotic objects don't behave that nice either. If you try to invoke [Symbol.iterator]()
on a typed array, map or set that is wrapped in a proxy, they'll bitch about being invoked on the wrong object.
Is this a V8 bug?
No, it's a bug in the application. You've got three choices:
[Symbol.iterator]
method does not typecheck its receiver.[[ProxyTarget]]
internal slot) then use that value. I would strongly advise against this, as it does not match the standard behaviour and breaches the proxy when bypassing the handler.Don't use a null proxy:
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);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With