What does the new keyword do under the hood?
I am curious as what else the new
keyword does in the background apart from changing what the this
scope refers too.
For example if we compare using the new
keyword to make a function set properties and methods on an object to just making a function return a new object, is there anything extra that the new object does?
And which is preferred if I don't wish to create multiple objects from the function constructor
var foo2 = function () {
var temp = "test";
return {
getLol: function () {
return temp;
},
setLol: function(value) {
temp = value;
}
};
}();
var foo = new function () {
var temp = "test";
this.getLol = function () {
return temp;
}
this.setLol = function(value) {
temp = value;
}
}();
The firebug profiler tells me using the new keyword is slightly faster (2ms instead of 3ms), on large objects is new still significantly faster?
[Edit]
Another matter is on really large object constructors is having a return at the bottom of the function (It will have a large amount of local functions) or having a few this.bar = ... at the top of the function more readable? What is considered a good convention?
var MAIN = newfunction() {
this.bar = ...
// Lots of code
}();
var MAIN2 = function() {
// Lots of code
return {
bar: ...
}
}();
Quoting Douglas Crockford from the Good Parts book (page 47), to answer the title of this question:
If the
new
operator were a method instead of an operator, it could be implemented like this:
Function.method('new', function () {
// Create a new object that inherits from the
// constructor's prototype.
var that = Object.create(this.prototype);
// Invoke the constructor, binding -this- to
// the new object.
var other = this.apply(that, arguments);
// If its return value isn't an object,
// substitute the new object.
return (typeof other === 'object' && other) || that;
});
The Function.method
method is implemented as follows. This adds an instance method to a class (Source):
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
Further reading:
- Mozilla Dev Center:
Object.create()
- Mozilla Dev Center:
Function.apply()
- Douglas Crockford: Classical Inheritance in JavaScript
Read the spec. Sections 11.2.2 and 13.2.2 are relevant and aren't too tricky to understand (note that the latter two links are to non-official HTML-ified version of the spec).
In summary, if you have a function f
that returns an object, the only observable difference that calling it with new
will make is that the this
value will be different, and that calling it with new
may be slower, since it involves additional steps of creating an object and assigning it a few properties.