Function.prototype, [[Call]] and [[Construct]]
On Nov 9, 2009, at 6:50 PM, Garrett Smith wrote:
[[Construct]] of Function.prototype is not standardized.
The definition of Function.prototype does not define the expected behavior for [[Call]] or [[Construct]]. Instead, there is a description of what happens when it is invoked:
| 15.3.4 Properties of the Function Prototype Object | The Function prototype object is itself a Function | object (its [[Class]] is "Function") that, when | invoked, accepts any arguments and returns undefined.
Should Function.prototype implement [[Construct]]? Either way, the specification should state the outcome.
Yes, it's a slightly tricky one :) I was wading through Sputniktests
suite couple of days ago (when finishing web runner — thinkweb2.com/projects/prototype/sputniktests-web-runner
) and noticed that there were assertions for exactly this kind of
compliance.
I even filed a bug with Sputniktests, thinking that they make
incorrect assumptions — code.google.com/p/sputniktests/issues/detail?id=11
However, then I realized that specs do in fact mention this
explicitly, although not directly under these specific sections.
If you look into Section 15 — Native ECMAScript Objects, you'll see
this rather clear explanation:
"[...] None of the built-in functions described in this section shall
implement the internal [[Construct]] method unless otherwise specified
in the description of a particular function. None of the built-in
functions described in this section shall initially have a prototype
property unless otherwise specified in the description of a particular
function. [...]"
In fact, I mentioned this exact phrase when writing about bugs in
various browsers, revealed through Sputniktests web runner (thinkweb2.com/projects/prototype/sputniktests-web-runner/#construct-and-prototype-of-builtins
).
And as I said in a post, Firefox and Chrome, for example, fail a whole
bunch of tests due to most of built-in methods (like
Array.prototype.toString
, parseInt
or String.prototype.slice
)
implementing [[Construct]] and having .prototype properties.
[...]
On Mon, Nov 9, 2009 at 8:05 PM, Juriy Zaytsev <kangax.dev at gmail.com> wrote:
On Nov 9, 2009, at 6:50 PM, Garrett Smith wrote:
[[Construct]] of Function.prototype is not standardized.
[...]
If you look into Section 15 — Native ECMAScript Objects, you'll see this rather clear explanation:
"[...] None of the built-in functions described in this section shall implement the internal [[Construct]] method unless otherwise specified in the description of a particular function. None of the built-in functions described in this section shall initially have a prototype property unless otherwise specified in the description of a particular function. [...]"
That's pretty clear. I had interpreted that as meaning the global functions (eval, parseInt), but now I see that that text applies to the whole section 15, not just the function properties (as I had misread it).
In fact, I mentioned this exact phrase when writing about bugs in various browsers, revealed through Sputniktests web runner (thinkweb2.com/projects/prototype/sputniktests-web-runner/#construct-and-prototype-of-builtins).
And as I said in a post, Firefox and Chrome, for example, fail a whole bunch of tests due to most of built-in methods (like
Array.prototype.toString
,parseInt
orString.prototype.slice
) implementing [[Construct]] and having .prototype properties.
So Function.prototype should not implement [[Construct]].
Garrett
On Nov 10, 2009, at 12:10 AM, Garrett Smith wrote:
On Mon, Nov 9, 2009 at 8:05 PM, Juriy Zaytsev <kangax.dev at gmail.com>
wrote:On Nov 9, 2009, at 6:50 PM, Garrett Smith wrote:
[[Construct]] of Function.prototype is not standardized.
[...]
If you look into Section 15 — Native ECMAScript Objects, you'll see
this rather clear explanation:"[...] None of the built-in functions described in this section shall implement the internal [[Construct]] method unless otherwise
specified in the description of a particular function. None of the built-in
functions described in this section shall initially have a prototype property
unless otherwise specified in the description of a particular function.
[...]"
[...]
So Function.prototype should not implement [[Construct]].
As far as I can see, no, it shouldn't.
WebKit (nightly) and Opera (10) conform here, throwing TypeError on
new Function.prototype
, but Firefox (at least 3.5) erroneously
creates an object.
[[Construct]] of Function.prototype is not standardized.
The definition of Function.prototype does not define the expected behavior for [[Call]] or [[Construct]]. Instead, there is a description of what happens when it is invoked:
| 15.3.4 Properties of the Function Prototype Object | The Function prototype object is itself a Function | object (its [[Class]] is "Function") that, when | invoked, accepts any arguments and returns undefined.
Should Function.prototype implement [[Construct]]? Either way, the specification should state the outcome.
Trying it out:
javascript: alert( new Function.prototype );
IE 6-8: Error: Object doesn't support this action
Other browsers tested return an Object, indicating the [[Construct]] is implemented.
The specification should state whether or not Function.prototype implements [[Construct]], to clarify expected outcome, and to encourage consistent implementations.
Garrett