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

David Flanagan dflanagan at mozilla.com
Fri Jun 17 14:03:54 PDT 2011


I'd like to follow up on this message from last month.  Has any decision 
been made about how a defineProperty() trap should reject the property 
definition attempt?  §4.6.4 of the latest WebIDL draft specifies a 
[[DefineOwnProperty]] algorithm with a Reject step that is dependent on 
the Throw argument.  And right now it can't really be implemented with a 
Proxy in a way that will work correctly when the proxy is used in 
non-strict code.

Tom suggested that defineProperty could return false or throw a 
TypeError to reject.  I assume that the proxy implementation would then 
do the right thing (return false or throw TypeError) based on the value 
of the Throw argument.

     David

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.
>
> 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/20110617/1f5ece1f/attachment.html>


More information about the es-discuss mailing list