May the defineProperty method of a proxy handler throw a TypeError?
seaneagan1 at gmail.com
Thu May 26 06:51:23 PDT 2011
Is think it would beneficial to replace all this.* calls in the
default trap implementations with Object.* methods and syntax that
subsequently triggers the this.* calls. This would guarantee that
none of the internal object semantics are being missed, and
implementations could still optimize just as easily.
On Thu, May 26, 2011 at 8:36 AM, Tom Van Cutsem <tomvc.be at gmail.com> wrote:
> Hi David,
> The short answer: if you also define a 'set' trap, throwing a TypeError from
> defineProperty() to signal rejection is appropriate.
> The longer answer:
> defineProperty() is based on [[DefineOwnProperty]] (ES5 section 8.12.9)
> whose rejection behavior depends on an explicit 'Throw' parameter, just like
> [[Put]] and [[Delete]]. Why then, do set() and delete() return a boolean
> success flag to determine their rejection behavior, while defineProperty()
> does not?
> I believe that, until now, we were convinced that in the case of proxies,
> defineProperty() actually does _not_ depend on strict mode, because the
> built-in Object.defineProperty and Object.defineProperties methods (ES5
> section 18.104.22.168-7) call the built-in [[DefineOwnProperty]] method with its
> 3rd argument 'Throw' set unconditionally to 'true', meaning it should never
> reject silently, independent of the strictness of the code.
> However, checking other parts of the spec where [[DefineOwnProperty]] is
> invoked, I now notice it's also invoked by [[Put]], which passes its own
> 'Throw' argument to [[DefineOwnProperty]], and this time, the 'Throw'
> argument is dependent on strict mode. This complicates matters because of
> derived traps.
> If a proxy handler does _not_ define a 'set' trap (which is derived), the
> proxy implementation will fall back on the fundamental defineProperty()
> trap, whose rejection behavior in that context now _should_ depend on strict
> mode. However, the current defineProperty() API doesn't allow the programmer
> to express this.
> I see two options here:
> 1) modify the defineProperty() trap such that it also returns a boolean flag
> to indicate rejection, like set() and delete(). This is still possible as
> defineProperty() currently has no useful return value.
> 2) specify unambiguously that defineProperty() on proxies should always
> reject explicitly by throwing a TypeError, even if the defineProperty() trap
> was called as part of the default 'set' trap.
> This can be justified if we specify that the default 'set' trap invokes the
> 'defineProperty' trap as if by calling "Object.defineProperty", which is
> specified to never reject silently.
> Option #1 would most closely follow the current ES5 spec, but would disallow
> since it's impossible to specify the value of the 'Throw' parameter
> Option #2 is in line with how the current default 'set' behavior is
> at <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.
> 2011/5/25 David Flanagan <dflanagan at mozilla.com>
>> I'm using a proxy to implement the DOM NodeList interface. A NodeList
>> object is array-like and has read-only, non-configurable array index
>> In my handler's set() and delete() methods, I just return false if an
>> attempt is made to set or delete an indexed property.
>> The defineProperty() method is not parallel to set() and delete(),
>> however. I can't just return false, since the return value is ignored. And
>> I can't tell from the proposal whether I am allowed to throw a TypeError
>> from this method. In getOwnPropertyDescriptor() I know that I have to lie
>> and return a descriptor with configurable:true for the indexed properties.
>> So in defineProperty() should I just silently ignore any attempts to set an
>> indexed property, or should I actively reject those attempts with a
>> es-discuss mailing list
>> es-discuss at mozilla.org
> es-discuss mailing list
> es-discuss at mozilla.org
More information about the es-discuss