slaphappy
slaphappy

Reputation: 6999

Javascript `new` keyword on function returning array

I was experimenting with the new keyword and I can't find an explanation for this behavior. Let's say we have a function returning an integer:

(In firebug)

>>> function x() { return 2; }
>>> x()
2
>>> new x()
x { }

But if the function returns an array :

>>> function y() { return [2]; }
>>> y()
[2]
>>> new y()
[2]

Why is that ?

Upvotes: 6

Views: 1750

Answers (2)

T.J. Crowder
T.J. Crowder

Reputation: 1074168

The new operator has an interesting behavior: It returns the object created by the operator unless the constructor function returns a different object. Any non-object return value of the constructor function is ignored, which is why when you return 2 you don't see this.

Here's what happens when you say new x():

  1. The interpreter creates a new blank object.
  2. It sets the object's underlying prototype to x.prototype.
  3. It calls x with this set to the new object.
  4. In the normal case, x doesn't return anything and the result of the new expression is the new object created in step 1. But, if x returns a non-null object reference, then that object reference is the result of the new expression rather than the object created in step 1. Any other kind of return value (null, primitive numbers, primitive strings, undefined, etc.) is ignored; it has to be a non-null object reference to take precedence over the object new created.

This special treatment given to object references by the new operator lets you substitute a different object for the one new created. This can be handy in some limited situations, but the vast majority of the time, a function designed to be used with new (called a constructor function) shouldn't return anything at all.

For some light reading (hah!), this is covered by Section 13.2.2 ("[[Construct]]") of the specification (HTML; PDF), which is referenced by Section 11.2.2 ("The new operator").

Upvotes: 16

Felix Kling
Felix Kling

Reputation: 816364

Because an array is an object but 2 is not.

If you call a function with the new keyword, it has to return an object. If you don't do that explicitly, it automatically returns this (which is an empty object that inherits from funcName.prototype).

Upvotes: 5

Related Questions