Do we really need the [[HasOwnProperty]] internal method and hasOwn trap

Tom Van Cutsem at
Mon Nov 12 13:00:43 PST 2012

2012/11/12 Allen Wirfs-Brock <allen at>

> I think the root issue relates to polymorphic dispatch of the internal
> methods and the transparent forwarding of unhanded traps to the Proxy
> target object.
> Every-time the spec. calls an internal method it is implicitly doing a
> polymorphic dispatch using that object's "handler"  as the "type". (we can
> think of ordinary objects as having a intrinsic handler that dispatches to
> the ordinary implementation of the internal methods).  The specification's
> implementation of the ordinary internal methods generally assumes that the
> "this object" that the internal method is operating upon is the object that
> did the original polymorphic dispatch (remember, no inheritance of internal
> methods).  This means that within those internal method algorithms it can
> be assume that a self-calll to an internal method will dispatch to the same
> ordinary handler.  [[HasProperty]] can self-call [[HasOwnProperty]] safely
> assuming that it will be using the same two coordinated implementation.
> However, if the ordinary [[HasProperty]] is being evaluated on a Proxy
> target because it was forwarded by the Proxy [[HasProperty]], its "this
> object" is the target, not the proxy and so its call to [[HasOwnProperty]]
> dispatches via the target and not the proxy.  We get an answer that is
> consistent, relative to the target object but not consistent relative to
> the proxy-based object that [[HasProperty]] was originally invoked upon.

Yes, this is a good summary of the issue, which I'll call the
"forwarding-footgun". But let me make a further distinction as there are
two ways in which an inconsistency between fundamental and derived traps
can occur:

1) a proxy handler implements a derived trap, but forgets to implement the
associated fundamental trap.
2) a proxy handler implements a fundamental trap, but forgets to implement
the associated derived traps.

1) is what you described above.

2) can be solved by having the handler subclass the standard Handler (see <>): by
"subclassing" the Handler and overriding some fundamental traps, one is
guaranteed that any derived traps will automatically call the overridden
fundamental trap.

> What we have is a situation that is very similar to that which requires
> the inclusion of a receiver argument in [[GetP]]/[[SetP]] calls, but along
> a different dimension.

I don't yet see how the "receiver" argument is similar to fusing derived
and fundamental traps into a single trap.

> Note that the "invariant enforcement" technique still doesn't allow a
> proxy with non-config/non-extensibility invariants to lie about its own
> properties. There are post-condition assertions on both
> "getOwnPropertyDescriptor" and "hasOwn" that ensure this. More generally:
> as long as a proxy p doesn't answer "true" to Object.isFrozen(p), its
> behavior can be arbitrary. Only when some sensible invariants are
> established on the proxy's target is the proxy's behavior restrained.
> Yes, and the concern is that most Proxy uses will not be in the context of
>  frozen object so in most cases none of the "invariant  enforcement" will
> not help with this problem.

I may have been misunderstood: I didn't claim that invariant enforcement
solves the forwarding-footgun, only that the inconsistent behavior caused
by the forwarding-footgun is not in itself an issue. It doesn't invalidate
code that relies on invariants.

> I've never been a big fan of dynamic invariant enforcement for proxies and
> I'm still not.  I am concerned that the current interfaces and factoring of
> derived/fundamental along with the target forwarding semantics is a footgun
> that is going to led to difficult to identify bugs.

Hold on: the invariant enforcement mechanism to me feels entirely
independent of the derived/fundamental trap distinction. We still need
invariant enforcement even if we fuse all derived traps into the
fundamentals (or get rid of the derived traps entirely).

For now, I can spec. the current factoring I think we should continue to
> look at it from this perspective and see if we can minimize the size of the
> footgun.

I agree we should keep the options open. As I mentioned above, the
'Handler' standard object, when used appropriately, can remedy one half of
the forwarding-footgun.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list