2010-03-24 59 views
12

鑑於這種很熟悉的原型構建的模型:使用'new'的調用函數比沒有它更便宜?

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

誰能解釋爲什麼叫new Rectangle(2,3)是一致的10倍比調用Rectangle(2,3)沒有「新」的關鍵字更快?我會假設,因爲通過獲取原型來增加執行函數的複雜性,它會變慢。

例子:

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 

回答

17

當你調用該函數不 「新」,它是什麼,你懷疑 「這」指向?這將是「窗口」。更新速度比在更新新建的新對象時要慢一些,這些新對象將在您使用「新建」調用時使用。

變化的第二個版本,以這樣的:

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

這將節省每次迭代重建虛擬對象的成本。

+0

你是對的。謝謝! – 2010-03-24 15:34:59

+0

當我這樣做時,我在新對象上執行了約148毫秒的執行。不如調用新的速度快,但比觸摸文檔要快得多。 – 2010-03-24 15:37:58

+0

正確 - 還要注意在第二個版本中還有調用「調用」函數的開銷。我懷疑V8有一個非常優化的「新」實現(實際上這很清楚你的數字)! – Pointy 2010-03-24 15:43:06

相關問題