What is the difference between calling myFoo = Foo(5)
and myFoo = new Foo(5)
?
There's no difference for that code, because it returns an object, and the spec says:
- Let result be the result of calling the [[Call]] internal property of F, providing obj as the
this
value and providing the argument list passed into [[Construct]] as args.
- If
Type(result)
is Object
then return result.
Since that function returns a result that is an Object, its result is used. You would notice a difference if it did not return an object, or if it checked this
, for example if you rewrote it as:
function Foo(x) {
if (!(this instanceof Foo)) { return new Foo(x); }
this.bar = function() { return x; };
}
// Now instanceof works.
alert((new Foo) instanceof Foo);
What does new
in JavaScript do, anyway?
The new
operator causes the function to be called with this
bound to a newly created Object
whose prototype is that function's prototype
property.
For user-defined functions,
new f(a, b, c)
is equivalent to
// Create a new instance using f's prototype.
var newInstance = Object.create(f.prototype), result;
// Call the function
result = f.call(newInstance, a, b, c),
// If the result is a non-null object, use it, otherwise use the new instance.
result && typeof result === 'object' ? result : newInstance
Note, that the language specification actually defines functions with two operations, [[Call]] and [[Construct]], so there are some corner cases where new
behaves oddly.
For example, bound and built-in functions:
var g = f.call.bind(f);
should define a function that when called, just calls f
, so g
should be the same as f
in all respects, but
new g()
produces
TypeError: function call() { [native code] } is not a constructor
because the builtin function Function.prototype.call
supports [[Call]] but not [[Construct]].
Function.prototype.bind
also behaves differently around new
and regular calls. The this
value is always the bound thisValue when called, but is a newly constructed instance when you use new
.