May the defineProperty method of a proxy handler throw a TypeError?

David Flanagan dflanagan at mozilla.com
Thu May 26 09:35:00 PDT 2011


On 5/26/11 6:36 AM, Tom Van Cutsem wrote:
> Hi David,
>
> The short answer: if you also define a 'set' trap, throwing a 
> TypeError from defineProperty() to signal rejection is appropriate

Thanks.  I was worried that defineProperty() was required to honor 
property changes since getOwnPropertyDescriptor() is required to say 
that the properties are configurable.  (I've read the justification for 
that in the proposal multiple times, but I've never been able to 
understand it...)

> 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 15.2.3.6-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 the default 'set' trap behavior from being written in 
> Javascript itself, since it's impossible to specify the value of the 
> 'Throw' parameter in Javascript.
>
> Option #2 is in line with how the current default 'set' behavior is 
> specified at 
> <http://wiki.ecmascript.org/doku.php?id=harmony:proxies#trap_defaults>.
>
> Cheers,
> Tom
>
> 2011/5/25 David Flanagan <dflanagan at mozilla.com 
> <mailto: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 properties.
>
>     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 TypeError?
>
>     _______________________________________________
>     es-discuss mailing list
>     es-discuss at mozilla.org <mailto:es-discuss at mozilla.org>
>     https://mail.mozilla.org/listinfo/es-discuss
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110526/2830a551/attachment.html>


More information about the es-discuss mailing list