使用'new'调用函数比不使用它更便宜?

时间:2010-03-24 15:31:14

标签: javascript class constructor prototypal-inheritance

鉴于这种非常熟悉的原型构造模型:

function Rectangle(w,h) {
    this.width = w;
    this.height = h;
}
Rectangle.prototype.area = function() { 
    return this.width * this.height;
};

有人可以解释为什么在没有'new'关键字的情况下调用new Rectangle(2,3)比调用Rectangle(2,3)快10倍?我会假设因为new会因为涉及到原型而增加了函数执行的复杂性,所以它会更慢。

示例:

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);

收益率(在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) rect 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

1 个答案:

答案 0 :(得分:17)

当您调用没有“new”的函数时,您怀疑“this”指向的是什么?它将是“窗口”。更新比使用“new”调用它时更新新构建的新对象要慢。

将第二个版本更改为:

trackFunction('rect classic (without new)', function() {
    Rectangle.call({}, 2,3);
}, TIMES);

看看你得到了什么。另一件事是:

trackFunction('rect with constant object', (function() {
  var object = { height: 0, width: 0 };
  return function() {
    Rectangle.call(object, 2, 3);
  };
})());

这将节省每次迭代重建虚拟对象的成本。