DOM bindings in some cases use a GetPropertyOnPrototype method to implement the semantics of a proxy that exposes a property *iff* there's no "overriding" version of that property along the proxy's prototype chain. The implementation of GPOP more or less gets the proxy's prototype, then does a get on the prototype of that property. In doing a get, this raises the question of what receiver to use for the get: the proxy, or the prototype? But given that WebIDL only really speaks in terms of [[GetOwnProperty]] overriding, and that method doesn't have a sense of receiver, the proxy seems likely to be impossible to pass in. The prototype is of course possible, but it seems a possibly weird thing to pass in. I'm told these are the relevant bits of spec: https://heycam.github.io/webidl/#getownproperty https://heycam.github.io/webidl/#dfn-named-property-visibility And that loop in step 7 in the latter looks like it's not actually doing a get -- just (if I squint a little and fuzz some language) a bunch of [[GetOwnProperty]] calls. So by doing a get and exposing a receiver, we currently appear to implement the wrong semantics for this. We should instead be walking the prototype chain doing own-property-lookups, using the hasOwnProperty optimization we have. Or something like that. This should be a visible difference in behavior if someone mutates the prototype chain of one of these DOM proxies to include a custom scripted proxy whose [[Get]] hook examines the identity of |this|.
So first off, I can't recall whether we'd decided [[GetOwnProperty]] was enough for Web IDL or whether it needed to define [[Get]] too (or was that [[Set]]? Jason do you recall?) to deal with some of this overridebuiltins stuff. Past that, I think you're right that the current Web IDL spec basically says to walk the proto chain doing http://people.mozilla.org/~jorendorff/es6-draft.html#sec-hasownproperty (though it could be more explicit about this). The annoying thing, then, is having to walk the proto chain twice.... I'm not sure there's any way to avoid that given how the spec is written right now, though; scripted proxies just expose too much of the MOP (including proto gets; the loop in step 7 of dfn-named-property-visibility is nonsense in the proxy world where the proto doesn't live in an internal [[Prototype]] slot on all objects).
Cameron, thoughts on comment 1?
Yeah, I guess we should be more explicit about invoking [[HasOwnProperty]]. And calling [[GetPrototypeOf]]. I don't think I ever considered author-implemented proxies being in the proto chain here. I don't like that the named property visibility algorithm invocation is observable to script. Given named properties are an oddity, and it's quite unlikely people are relying on specific behaviour with proxies in the proto chain, can we just ignore them if we encounter them in the named property visibility algorithm?
(In reply to Cameron McCormack (:heycam) from comment #3) > Given named properties are an oddity, and it's quite > unlikely people are relying on specific behaviour with proxies in the proto > chain, can we just ignore them if we encounter them in the named property > visibility algorithm? Ignore proxies in the prototype chain if you encounter them, you say? How? By design proxies are not supposed to be recognizable as such. It would be quite unusual to make such a distinction here.
Presumably we can tell in C+. But if that is not the proper thing to do (it'd be another example of something that C++ could do that script couldn't do), OK.
C++ could be made to tell. But from a specified-behavior point of view, the question is not something ESmumble is ever going to ask, or provide well-supported ways to do, because the question is -- yes -- improper, given that proxies are supposed to be fully featured enough to implement anything. :-) I don't think you should be going behind the spec's back to ask the question.
...implement anything, without code that uses such a proxy being able to tell what implemented it.
While all this is true, the spec does have a concept of "ordinary object", sufficiently to be able to do things like assert that something is an "ordinary object". Of course that's not quite what we want here. More interestingly, ES6 is heavy into internal-slot-based duck typing and use presence or absence of internal slots all over the place. Web IDL is expected to do so too, for branding, as far as I can tell. Various ES6 objects have an internal slot called [[Prototype]]. Proxies do not. Proxies have a [[ProxyHandler]] internal slot. So we could in fact tell apart proxies and non-proxies in what looks to me like the spec-blessed way of telling things apart: by examining the internal slots. Whether we want to do that is a separate question, and this "examine the internal slots" business is, of course, not directly exposed to script so couldn't be implemented by a scripted proxy... All that said, I would _really_ like an effectless named property visibility algorithm if we can somehow produce one.
(In reply to Boris Zbarsky [:bz] from comment #8) > All that said, I would _really_ like an effectless named property visibility > algorithm if we can somehow produce one. We could ignore the prototype chain and look at the set of interface prototype objects that exist before script tries to mess with it. So the named property visibility algorithm for say HTMLFormControlsCollection would call [[HasOwnProperty]] on the initial HTMLFormControlsCollection.prototype object, the initial HTMLCollection.prototype object, then the initial Object.prototype object. We know that these won't be proxies.
Hmm. That might be nice, yeah. I wonder what browsers do right now in practice if you rearrange the proto chain of an HTMLCollection...
You need to log in before you can comment on or make changes to this bug.