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

Andreas Rossberg rossberg at
Thu May 26 11:12:13 PDT 2011

On a somewhat related note, I recently noticed that the semantics of
[[GetProperty]] and [[GetOwnProperty]], according to,
contain a possible "reject" step, which doesn't seem to be
well-defined given that these method have no Throw parameter either.


On 26 May 2011 15:36, Tom Van Cutsem < at> 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 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 <>.
> Cheers,
> Tom
> 2011/5/25 David Flanagan <dflanagan at>
>> 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
> _______________________________________________
> es-discuss mailing list
> es-discuss at

More information about the es-discuss mailing list