What is the distinction between using myFoo = Foo(5)
versus myFoo = new Foo(5)
?
In this scenario, there actually isn't a difference because both methods result in an object being returned. According to the specification:
- Let result be the outcome of invoking the [[Call]] internal property of F, with obj as the
this
value and the argument list provided into [[Construct]] as args.
- If
Type(result)
is Object
, then return result.
Since the function returns an Object as its result, either method can be used interchangeably. A discrepancy would only arise if it did not return an object or if it checked this
, such as in this example:
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 exactly does the new
operator do in JavaScript?
The new
operator results in the function being invoked with this
bound to a freshly created Object
whose prototype is the function's prototype
property.
For user-defined functions,
new f(a, b, c)
is essentially equivalent to
// Create a new instance using f's prototype.
var newInstance = Object.create(f.prototype), result;
// Invoke 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
It's important to note that the language specification defines functions with two operations, [[Call]] and [[Construct]], which leads to some peculiar behaviors when using new
.
For instance, bound and built-in functions:
var g = f.call.bind(f);
should create a function that merely calls f
; thus, g
should behave identically to f
. However, when doing:
new g()
a
TypeError: function call() { [native code] } is not a constructor
error occurs since the built-in function
Function.prototype.call
supports
[[Call]] but not
[[Construct]].
Additionally, Function.prototype.bind
displays different behavior between new
and regular calls. The this
value is always the bound thisValue during a regular call, whereas it becomes a newly constructed instance when using new
.