Weird spec hole in ES3 and ES5
Allen.Wirfs-Brock at microsoft.com
Thu Jul 2 09:26:30 PDT 2009
>From: es5-discuss-bounces at mozilla.org [mailto:es5-discuss-
>bounces at mozilla.org] On Behalf Of Maciej Stachowiak
>Sent: Tuesday, June 23, 2009 11:19 AM
>To: Mark S. Miller
>> The documentation of .call(), .apply(), and .bind() are in terms of
>> invoking an internal [[Call]] (or for .bind(), also a [[Construct]])
>> property). However, the Ch15 constructor documentation doesn't
>> actually mention these internal property names. It explains instead
>> what happens when a constructor is called as a constructor (with
>> "new"), which is probably adequate to infer the behavior of the
>> [[Construct]] property. And it explains what happens when a
>> constructor is called as a function. But it is not clear from the
>> latter what, if anything, one should infer about the constructor's
>> [[Call]]. In particular, what should happen when .call(), .apply(),
>> or .bind() causes a Ch15 constructor's [[Call]] to be invoked with a
>> thisArg that either 1) does not inherit from that
>> constructor's .prototype, or 2) does not have the [[Class]] that the
>> constructor would normally place on the newly constructed object?
>It could be made more clear that the "when called as a function" and
>"when called as a constructor" descriptions correspond to the [[Call]]
>and [[Construct]] internal properties respectively. Perhaps a single
>sentence at the start of the built-in object section could take care
Because built-in constructors are not (necessarily) implemented in ECMAScript code they are not required to use the definitions of [[Call]] and [[Construct]] given in 13.2.2 and 13.2.3. Arguably the "Constructor Called as a Function" and "called as part of a new expression" sections of chapter 15 are specifying the behavior of custom [[Call]] and [[Construct]] internal methods for each built-in constructor.
I'll see if can find a way to clarify this in the introduction to chapter 15.
>> One interpretation of "called as a function" in the Ch15 constructor
>> documentation is that the thisArg (since it is never mentioned) is
>> always ignored. This seems consistent with the behavior I just
>> observed on FF3.0.10, Safari 3.2.3, and Chrome 3.0.189 on the Mac.
>> This seems fine, except that it means one cannot use the normal
>> "subclassing"ish pattern for defining new error constructors that
>> extend Error, since Error will ignore the normal constructor
>> chaining. Is this intended?
>I think this should be the behavior. Built-in or host constructors
>always make a brand-new object of a specific [[Class]], they ignore
>the object that would be passed in by "new" for a JS-implemented
>constructor function. The spec for Error seems unclear on this since
>it refers to "the newly constructed object" without clearly explaining
>how it is created.
Actually, I think the spec. language is pretty clear on this for Error in both ES5 and ES5 (same basic language). 15.11.1 says "When Error is called as a function rather than as a constructor, it creates and initialises a new Error object. " The phrase "the newly constructed object" in 126.96.36.199 seems to clearly be a reference to that new Error object.
More information about the es-discuss