Property Descriptors as script compatible representation (was: Property descriptors as ES6 Maps)

Tom Van Cutsem at
Fri Nov 2 04:20:04 PDT 2012

Hi Allen,

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

> The above isn't how this will be expressed in the final spec.  Instead we
> will have
> 3) Let desc be the result of calling the [[GetOwnProperty]] internal
> method of O with argument name.
> 4) Return the result of calling FromPropertyDescriptor(desc) (8.10.4).
> And all Proxy objects will have a [[GetOwnProperty]] internal methods that
> looks something like:
> 1) Let O be the object upon which this internal method was invoked.
> 2) Let desc be the result of calling TrapGetOwnProperty(O,name)
> 3) Return ToPropertyDescriptor(desc)
> (I left out details of exception handling)

Actually, while reviewing the spec, I realized that there is a good reason
why the spec isn't currently specified this way (i.e. why the Proxy spec
redefines Object.defineProperty and Object.getOwnPropertyDescriptor and
does not just override [[DefineOwnProperty]] and [[GetOwnProperty]])

It is to avoid the lossy conversion that otherwise occurs between the
return value of [[GetOwnProperty]] and Object.getOwnPropertyDescriptor.

With your alternative spec above, consider a call to
|Object.getOwnPropertyDescriptor(proxy, name)|

1. The Object.gOPD built-in calls proxy.[[GetOwnProperty]]
2. [[GetOwnProperty]] invokes the trap, gets back an object
3. [[GetOwnProperty]] converts the object into an internal descriptor and
4. Object.gOPD takes this internal descriptor and turns it into an object

Not only are steps 3. and 4. logical inverses, they lose information:
recall that we had previously decided that custom attributes on property
descriptors would be passed through. So if a proxy trap returns the
descriptor {value:42, custom: true}, we want clients to still see the
"custom" attribute. That's why we need to avoid coercing the trap result to
an internal descriptor.

The case for Object.defineProperty is entirely analogous.

That's why there exist TrapDefineOwnProperty and TrapGetOwnProperty
auxiliary functions: they abstract the common parts between the Object.*
built-ins and the internal methods without doing conversions. This is so
that the Object.* built-ins can call these auxiliaries directly, and avoid
the conversions.

I realize you want to avoid explicit tests for proxies as much as possible.
One way to do that would be to introduce two new built-ins, so that we end
up with:
[[GetOwnProperty]]( P ) -> PropDesc (same as ES5)
[[GetOwnPropertyObject]] ( P) -> Object (called by Object.gOPD)
[[DefineOwnProperty]] (P, PropDesc) -> Boolean (same as ES5)
[[DefineOwnPropertyObject]] (P, Object) -> Boolean (called by

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

More information about the es-discuss mailing list