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 ?
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 ?
Share Improve this question asked Jun 27, 2011 at 9:39 slaphappyslaphappy 6,9993 gold badges35 silver badges59 bronze badges 7-
2
Off-topic: I know you're just experimenting, but it's worth getting in the habit early and if you're experimenting you may not (yet) know this: The overwhelming convention in JavaScript code is that the names of constructor functions (functions you use with
new
rather than just calling directly) start with a capital letter, and the names of all other functions start with a lower-case letter. SoFoo
would be a constructor function, andfoo
would not. – T.J. Crowder Commented Jun 27, 2011 at 9:51 - Is this valid javascript? Why have you called x() on its own with no semi-colon? – Exitos Commented Jun 27, 2011 at 9:53
- 1 @Pete2k: Looks like kbok is playing around in a JavaScript console. Also, semicolons are optional in JavaScript, statements can also be terminated by an EOL. – mu is too short Commented Jun 27, 2011 at 9:54
- @Pete2k: Why should it not be valid? It's a function. Semi-colons are optional. – Felix Kling Commented Jun 27, 2011 at 9:54
- this is because I'm typing it in the firebug console. – slaphappy Commented Jun 27, 2011 at 9:55
2 Answers
Reset to default 16The 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()
:
- The interpreter creates a new blank object.
- It sets the object's underlying prototype to
x.prototype
. - It calls
x
withthis
set to the new object. - In the normal case,
x
doesn't return anything and the result of thenew
expression is the new object created in step 1. But, ifx
returns a non-null
object reference, then that object reference is the result of thenew
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 objectnew
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").
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)
.