2011-09-22 212 views
1

我再次在Internet上發現了包含內聯函數的JavaScript代碼,在我看來,常規語句的意義非常重要。這是第一個示例:JavaScript:內聯函數與常規語句

function outerHTML(node){ 
    // if IE, Chrome take the internal method otherwise build one 
    return node.outerHTML || (
     function(n) { 
      var div = document.createElement('div'), h; 
      div.appendChild(n.cloneNode(true)); 
      h = div.innerHTML; 
      div = null; 
      return h; 
     })(node); 
} 

如果你問我的代碼同樣的事情,它應該是這樣的:

function outerHTML(node){ 
    var div, h; 

    // if IE, Chrome take the internal method otherwise build one 
    if (node.outerHTML) { 
    return node.outerHTML; 
    } 

    div = document.createElement('div') 
    div.appendChild(node.cloneNode(true)); 
    h = div.innerHTML; 
    div = null; 

    return h; 
} 

編輯作爲OverZealous stated,有這一個邏輯上的差異。我把它留在這裏,所以沒人會對這個答案感到困惑。

也許再原始樣本(是的,這不 「編譯」,因爲它只是一個代碼片段):

addGetters: function (attributes) { 
    var that = this; 
    function addGetter(attr) { 
    that.prototype["get" + attr.capitalize()] = function() { return this[attr]; }; 
    } 

    for(var i = 0; i < attributes.length; i++) { 
    var attr = attributes[i]; 
    addGetter(attr); 
    } 
}, 

相比,我嘗試

addGetters: function (attributes) { 
    for(var i = 0; i < attributes.length; i++) { 
    var attr = attributes[i]; 
    this.prototype["get" + attr.capitalize()] = function() { return this[attr]; }; 
    } 
}, 

有區別嗎?原始版本不需要更多的空間,因爲需要創建一個函數和/或不是因爲這個更慢?有沒有可能的內存泄漏?

CPU和內存的使用非常重要,因爲我在一個環境中進行編碼,因爲兩者都是有限的,任何「少」都是好的。而且由於JavaScript中沒有sizeof(),並且它的實現嘗試不能安全地解釋任何想法 - 提前修復很重要。

請注意,就「我的版本」而言,我沒有對它進行測試。我只是想解釋我想問的問題。

編輯:即使這個問題有答案,我仍然想知道內存利用率。如果有人有一些見解,請不要猶豫,在這裏添加它。

回答

0

由於OverZealous pointed out,需要確定發生的邏輯。 +1。

就性能而言,我終於有時間自己做一些測試。但是,我正在一個無法真正檢查內存使用情況的環境中工作。所以我試圖欺騙表演。

結果是,它可能會影響取決於使用此功能的頻率。在我的目標系統上,簡單地創建了幾乎沒有任何東西的內聯函數,例如

myArray.each(function inlineFunc(el) { return el; }); 

花費這樣的功能的萬個創作約1.8秒(在上面myArray的例子中沒有元素)。相比之下,該瀏覽器的個人電腦版本需要1,000,000次迭代才能到達接近的地方(顯然這也取決於硬件)。由於在我們使用的代碼中(不是直接在一個循環中,而是在整個代碼中創建函數)達到10,000次迭代,我們將與我們的分包商有一個詞。

2

對於第一個,我不相信這個功能是有任何理由的。它可能已經(d)通過小的改變進入該狀態,但額外的函數包裝器沒有提供我可以看到的任何好處。

然而,第二個例子實際上對使用函數包裝很重要。原因是由於JavaScript(有時令人沮喪)的功能級範圍。在你的例子中,只有一個attr變量。它在不同的屬性中共享。這意味着,最終,每個屬性將返回數組中最後一個屬性的值。

e.g:

var attrs = ['foo', 'bar', 'baz'] 
obj.addGetters(attrs); 

obj.getFoo(); // returns obj.baz 
obj.getBar(); // returns obj.baz 

通過在功能包裝,吸氣創作,你消除這種問題,因爲attr最終被作用域爲創建功能。這就是爲什麼Douglas Crockford的JSLint說「不要在循環內創建函數」。它會導致這樣的意外錯誤。

+0

我應該包括[鏈接到JSLint](http://www.jslint.com/)。 – OverZealous

+0

好的,所以這是第二個示例中與邏輯有關的問題。也許我可以找到另一個樣本。但是,迄今爲止感謝。 – sjngm

-1

答案在於旁觀者的眼中。
這是一個偏好問題。
如果你把「速度」以上的模塊化,這取決於你。
問問自己:爲什麼在使用while時可以使用for?事實證明,在某些情況下,while結構更快一些。

+0

我不明白這是一個答案。我說速度和記憶是關於這個問題的一個重要問題。這不是一種偏好,這是如何。此外,我並沒有要求比較'for'和'while'。 – sjngm