Given this very familiar model of prototypal construction:
function Rectangle(w,h) {
this.width = w;
this.height = h;
}
Rectangle.prototype.area = function() {
return this.width * this.height;
};
Can anyone explain why calling new Rectangle(2,3)
is consistently 10x FASTER than calling Rectangle(2,3)
without the 'new' keyword? I would have assumed that because new adds more complexity to the execution of a function by getting prototypes involved, it would be slower.
Example:
var myTime;
function startTrack() {
myTime = new Date();
}
function stopTrack(str) {
var diff = new Date().getTime() - myTime.getTime();
println(str + ' time in ms: ' + diff);
}
function trackFunction(desc, func, times) {
var i;
if (!times) times = 1;
startTrack();
for (i=0; i<times; i++) {
func();
}
stopTrack('(' + times + ' times) ' + desc);
}
var TIMES = 1000000;
trackFunction('new rect classic', function() {
new Rectangle(2,3);
}, TIMES);
trackFunction('rect classic (without new)', function() {
Rectangle(2,3);
}, TIMES);
Yields (in Chrome):
(1000000 times) new rect classic time in ms: 33 (1000000 times) rect classic (without new) time in ms: 368 (1000000 times) new rect classic time in ms: 35 (1000000 times) r开发者_运维问答ect classic (without new) time in ms: 374 (1000000 times) new rect classic time in ms: 31 (1000000 times) rect classic (without new) time in ms: 368
When you call the function without "new", what is it that you suspect "this" is pointing to? It'll be "window." Updating that is slower than updating the freshly-built new object you'll be using when you invoke it with "new".
Change the second version to this:
trackFunction('rect classic (without new)', function() {
Rectangle.call({}, 2,3);
}, TIMES);
and see what you get. Another thing to try would be this:
trackFunction('rect with constant object', (function() {
var object = { height: 0, width: 0 };
return function() {
Rectangle.call(object, 2, 3);
};
})());
That will save on the cost of rebuilding the dummy object on each iteration.
精彩评论