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

Tom Van Cutsem tomvc.be at gmail.com
Fri May 27 02:04:09 PDT 2011


Good catch. I count 5 occurrences of 'reject' on the page, 4 of these are
called when the corresponding trap is not defined on the handler. For these
cases, we should probably throw a TypeError, like we do for other traps
(like for fix() in Object.freeze and getOwnPropertyNames in
Object.getOwnPropertyNames).

For [[DefineOwnProperty]] and [[Delete]] I think we are unnecessarily
conflating this error condition with the notion of 'rejection'. And as you
note, for [[GetProperty]] and [[GetOwnProperty]] it isn't even well-defined.

2011/5/26 Andreas Rossberg <rossberg at google.com>

> On a somewhat related note, I recently noticed that the semantics of
> [[GetProperty]] and [[GetOwnProperty]], according to
> http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics,
> contain a possible "reject" step, which doesn't seem to be
> well-defined given that these method have no Throw parameter either.
>
> /Andreas
>
>
> On 26 May 2011 15:36, 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 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>
> >>
> >> 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
> >> https://mail.mozilla.org/listinfo/es-discuss
> >
> >
> > _______________________________________________
> > es-discuss mailing list
> > 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/20110527/29c175ae/attachment.html>


More information about the es-discuss mailing list