Is it possible to do new new A
in JS with A !== Function
? What's the desired structure of A then?

- 6,256
- 6
- 44
- 79
-
Did you mean `new A` instead? – Qantas 94 Heavy Aug 13 '14 at 13:06
-
possible duplicate of [What is the 'new' keyword in JavaScript?](http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript) – Qantas 94 Heavy Aug 13 '14 at 13:07
-
I'm aware what the `new` keyword is. Thank you. – polkovnikov.ph Aug 13 '14 at 13:12
2 Answers
Yes, in theory.
function A() {
return function B() {
}
}
> new new A
B {}
or
> new new A()
> new new A() ()
since the parentheses are optional with the new
operator.
This takes advantage of the fact that a constructor may return something other than the constructed object. It is extremely unclear why anyone would ever want to do this. Also, this does not change the fact that new
can only be invoked on a function.
Dept. of Curiosities
This
function A() { return A; }
allows you to do this
new new new new new new new new new new new new A
which there is no point whatsoever in doing.
Prototype Chains
You know that calling new
on a constructor constructs an object with the prototype for that constructor. However, if you return any object other than this
from a constructor, this
, along with its associated prototype, is forever lost to the world. Whatever object you return has its own prototype, coming from wherever--not that of A. This applies equally to the case here where the constructor returns a function, in which case the relevant prototype is Function.prototype
. Is there any way to arrange it, in the unlikely event that we cared, so that new A
continues to return a functioning function, which we can do a new
on, while also having access to A.prototype
?
Not easily. If you want additional properties on the function B
returned from new A
, then you can just add those properties before returning function B
.
-
Excellent! That's the answer I've been expecting. Is it a standard-compliant behaviour? – polkovnikov.ph Aug 13 '14 at 13:18
-
1@polkovnikov.ph Yes, this is perfectly valid ECMAScript behavior per the [`[[Construct]]` specifiction](http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.2): `Let result be the result of calling the [[Call]] internal property... If Type(result) is Object then return result.` (i.e., if the function's behavior when called returns an object, use that object as the return value of the constructing `new` call). Functions are objects, so it's a valid return value for a constructor. – apsillers Aug 13 '14 at 13:21
-
@torazaburo Don't you have an idea on how to restore a prototype chain there? – polkovnikov.ph Aug 13 '14 at 13:50
-
@polkovnikov.ph `A` is a function that constructs a constructor (we'll call this constructed constructor `B`). When you construct an instance of `B`, the instance uses `B`'s prototype chain. Simply build your prototype chain around `B` in instead of `A` -- `A` is a constructor that makes constructors, not proper objects. If using `B.prototype` is not practical for some reason (you haven't said *why* on earth you need to support `new new A`), you can also have `B` return an object created with `Object.create(A.prototype)`. – apsillers Aug 13 '14 at 13:57
-
@apsillers I forgot why on earth did I need it myself, but then remembered that I'd like to `var User = new Model(...), user = new User(...);`. – polkovnikov.ph Nov 13 '14 at 23:08
No, it's not possible. A
must be a function, regardless of its return value.
Source: ECMAScript 5 spec for the new
operator:
If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
From the Function specification, we can see that [[Construct]]
is a special internal (inaccessible) property of Function objects.

- 29,767
- 10
- 79
- 91
-
This is little more than a curiosity, but: the spec does not disallow non-function *host objects* from implementing an internal `[[Construct]]` property, though I don't know of any actual host environment that supplies non-function constructors. – apsillers Aug 13 '14 at 13:13
-
Should `A` be a function or `new A` be a function? Why is it impossible to tweak a constructor of a type so that constructed objects would have an internal `[[Construct]]`? – polkovnikov.ph Aug 13 '14 at 13:14
-
@polkovnikov.ph It is not possible to directly alter an object's internal properties from JS code, which is part of the reason why they're called "internal". To answer your first question: `A` must be a function and the result of `new A` must also be a function. – apsillers Aug 13 '14 at 13:16
-
Both `A` and `(new A)` must be functions or, as apsillers points out, special (probably non-existent) objects that the runtime endows with a `[[Construct]]` property. `[[Construct]]` is purely in the realm of the host runtime; the executed JavaScript code cannot touch it. – joews Aug 13 '14 at 13:16
-
1@joews Note that question specifies `A !== Function` not `typeof A != "function"` (that is, `A` could be a function, just not the particular `Function` constructor function), so it *is* technically possible, per torazaburo's answer. – apsillers Aug 13 '14 at 13:18
-