Weird spec hole in ES3 and ES5

Allen Wirfs-Brock Allen.Wirfs-Brock at microsoft.com
Thu Jul 2 10:39:53 PDT 2009


Here is the language that I have inserted in the introduction to Chapter 15:


This section generally describes distinct behaviours for when a constructors is "called as a function" and for when it is "called as part of a new expression". The "called as a function" behaviour corresponds to the invocation of the constructor's [[Call]] internal method and the "called as part of a new expression" behaviour corresponds to the invocation of the constructor's [[Construct]] internal method.


From: Mark S. Miller [mailto:erights at google.com]
Sent: Thursday, July 02, 2009 10:30 AM
To: Allen Wirfs-Brock
Cc: Maciej Stachowiak; Google Caja Discuss; es-discuss; es5-discuss at mozilla.org
Subject: Re: Weird spec hole in ES3 and ES5

On Thu, Jul 2, 2009 at 9:26 AM, Allen Wirfs-Brock <Allen.Wirfs-Brock at microsoft.com<mailto:Allen.Wirfs-Brock at microsoft.com>> wrote:

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.

The problem is that .call(), .apply(), and .bind() are specified in terms of [[Call]], so unless the connection is somehow made, it technically becomes unspecified how native constructors respond to these reflective operations.

AFAIK, the observed behavior across browsers is consistent with the theory that "called as a function" actually documents the constructor's [[Call]] method.


I'll see if can find a way to clarify this in the introduction to chapter 15.

Some introductory text there would be adequate. No need to propagate local changes.

In my initial message, I was also confused about whether "called as a function" was meant to cover cases such as

    foo.Error(x, y)

which I normally distinguish by saying "called as a method". If this is not unclear in the context of the rest of the ES5 spec language, no further explanatory note is needed, but may be helpful to readers as confused as I.


>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.
>
>I think this should be the behavior. Built-in or host constructors
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 15.11.1.1 seems to clearly be a reference to that new Error object.

Actually, this reasoning helps clarify why there is currently a potential confusion. In a normal function call "Error(...)", there is no object explicitly passed in as the thisArg, so the spec language above does seem clear for that case. For the reflective or method cases there is an explicitly provided thisArg, so it is not unreasonable to guess that "the newly constructed object" may refer to that. Fortunately, the same simple clarification at the beginning of Ch15 should take care of this too.


--
   Cheers,
   --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20090702/50077531/attachment.html>


More information about the es-discuss mailing list