Weird spec hole in ES3 and ES5

Maciej Stachowiak mjs at
Tue Jun 23 11:19:05 PDT 2009

On Jun 22, 2009, at 6:02 PM, Mark S. Miller wrote:

> What does "Error.apply({}, [])" do? We ran into this issue in trying  
> to fix a Caja bug. Of course, the real question for Caja must be  
> what do browsers do today, which we can test. But I was curious what  
> the spec said. From the way the Ch15 constructors are documented, I  
> think in general we can't tell. ES3 and ES5 both seem to suffer from  
> the same hole in the spec language.
> 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  
of this.

> This same problem arises if a Ch15 constructor is called as a  
> method. What should "({foo: Error}).foo()" do?
> 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.


More information about the es5-discuss mailing list