6

I'm reading the latest ECMA-262 reference, edition 5.1 June 2011.

In section 8.6.2 table 9 we have in regard to the [[Construct]] internal property:

Creates an object. Invoked via the new operator. The arguments to the SpecOp are the arguments passed to the new operator. Objects that implement this internal method are called constructors.

The standard doesn't say that a constructor has to be a Function object. So can we have a constructor object that is not a function object?

Link to the standard as requested

Roland
  • 7,525
  • 13
  • 61
  • 124
  • Could you link to the spec document? I don't think many people will be able to answer without a fuller context for the quote you've supplied. (Interesting question, though!) – apsillers May 01 '12 at 05:47
  • 2
    You might be interested in the [Annotated ES5](http://es5.github.com/) which is a HTML conversion of the ECMA-262 5.1 standards PDF. It has section anchors such as the one for [Section 8.6.2](http://es5.github.com/#x8.6.2). – Dan D. May 01 '12 at 05:56
  • if I remember correctly, Crockford said that in general, using a constructor is not a good pattern in JS – thepoosh May 01 '12 at 06:00
  • 3
    You are *actually* reading the specs... Bravo. – Derek 朕會功夫 May 01 '12 at 06:13
  • @Thepoosh Crockford also claims that ++ operator is not a good patterns in JS... – Piotr Kochański May 01 '12 at 18:20
  • @PiotrKochański, He didn't say it a bad pattern, he said that he thinks its less readable. there's a major difference between the two – thepoosh May 02 '12 at 05:53

3 Answers3

4

The answer is extremely simple. ES5 § 4.3.4 says:

Constructor Function object that creates and initialises objects.

So there you have it, by definition only a Function can be a constructor. However, likely there are host objects that behave like constructors that do not have any of the other attributes of native Function objects (e.g. the original XMLHttpRequest object in IE that was implemented in ActiveX).

RobG
  • 142,382
  • 31
  • 172
  • 209
  • I'm accepting this as the answer. IMHO the spec is not entirely clear in that it seems that an object that is not a function can still have a [[Construct]] internal property, at least table 9 referenced in the question doesn't explicitly prohibit this. If anyone knows who the author of the spec is I would like to write him an email and ask for clarification. – Roland May 01 '12 at 07:03
3

While the term "Constructor" is defined (as @RobG pointed out), there is nothing that prevents a non-"Constructor" object from having a [[Construct]] method.

This is a bit confusing. It means you can use the new operator on an object that is not a Function (thus not a "constructor" as per 4.3.4 ), but does indeed provide a [[Construct]] method.

Note that none of the standard objects qualify for that, but host objects may indeed. A browser plugin such as Java may expose some object like so:

new java.lang.String(); // it works, so java.lang.String has a [[Construct]] method
java.lang.String instanceof Function // false
Object.prototype.toString.call(java.lang.String).indexOf('Function') // -1

Note that typeof java.lang.String returns "function" even though java.lang.String is not a function. This is correct according to 11.4.3 (it is a host object with a [[Call]] method)

Community
  • 1
  • 1
user123444555621
  • 148,182
  • 27
  • 114
  • 126
  • Next you will get lost in the semantics of "what is a function?". The spec only covers native objects (including built-ins) and explicitly allows host objects to do what they like. It makes sense for creators of host objects to follow ECMA-262, but there are many cases where they haven't, nice to see an example that isn't IE. :-) – RobG May 01 '12 at 22:16
  • @RobG Not sure what you are trying to say here. [8.6.2](http://es5.github.com/#x8.6.2) covers host objects to a certain extent. Also, the term "function" is defined in [4.3.24](http://es5.github.com/#x4.3.24) – user123444555621 May 01 '12 at 22:28
  • @RobG I think the problem is that the spec is not totally consistent. – Roland May 02 '12 at 01:14
  • @Pumbaa80—the part you reference says `Host objects **may** support these internal properties with **any implementation-dependent behaviour**...`, and places very few restrictions on that behaviour. Also, there are many callable host objects that don't adhere to the ECMAScript notion of a function (e.g. they aren't instances of Function). – RobG May 08 '12 at 00:03
  • Okay. It's all a bit confusing indeed. I think the spec's authors are well aware of the current implementations, and made the definitions exactly for those, intentionally allowing weird combinations like "callable host objects which are not functions". – user123444555621 May 08 '12 at 09:27
0

To add to Pumbaa80's answer (this would be too long for a comment).

The confusion is increased by 13.2.2 according to which when a function's construct is executed its call operation has to be executed(but it doesn't say what has to be done when the construct of an object that isn't a function is executed). Now, objects who implement call are callable function objects according to 9.11.

Also according to 4.2 "a function is a callable object". But of course this doesn't imply that every callable object is a function.

So if I got this right non Function objects can have a Construct method and also a Call method. java.lang.String would be one such example.

Community
  • 1
  • 1
Roland
  • 7,525
  • 13
  • 61
  • 124