2012-07-02 32 views
1

我正在處理一個太複雜(處理器)的函數,所以我在其中嵌入了一個嵌套的「實用程序函數」(print)中嵌入了部分功能。它簡化版本是這樣的:嵌套函數:我在這裏創建10個函數嗎?

var out = document.getElementById("output"); 

function processor (n) { 
    function print(msg) { 
     out.innerHTML += msg; 
    } 
    while (n > 0) { 
     print(n--); 
     print(", "); 
    } 
    print("<br/>"); 
} 

for (var i = 0; i < 10; i++) { 
    processor(i); 
} 

你可以看到它在行動this JSfiddle

問題是:我真的創建了10個實用函數print()的實例嗎?如果是的話,在沒有將效用函數放在processor()函數之外的情況下編寫該代碼的更有效方法是什麼?我希望print()函數只能在processor()和其他地方訪問。一種解決方案是命名空間。

我讀過這個問題,即使它有關,但它不是直接我的答案: Efficiency of creating an event handler in a nested loop: am I creating 1440 functions here?

+0

不計算函數問題,真正歸結爲GC,如下所述,甚至可以優化爲只重新分配環境,正如另一個答案中提到的,您不應該使用innerHTML和許多小數據片。以數組形式組裝它們,或者至少使用字符串並一次分配。 –

+0

是的,我知道innerHTML的性能問題。這只是一個看起來不同的代碼的簡單示例,但我不得不想出一些「print()」函數,而我不想使用console.log()。這只是一個即興即興;) – AlexStack

回答

1

總之,是的,你是。但是因爲它們都是本地函數,所以當函數返回時它們將被彈出堆棧並銷燬。由於您在for循環中以串行方式調用processor()函數,因此只有一次print()函數的實例在任何時間點都是有效且可訪問的。

+0

這就是我懷疑的。所以如果我想要代碼說「print()」只用在「processor()」中,也許我應該將它們嵌入到一個(function(){...})()中,然後使用生成的對象代替。 – AlexStack

+0

是的。而且,這將允許您在相同範圍內添加更多功能(即可訪問print()函數的功能),同時保持應用程序代碼的其餘部分清潔。 – techfoobar

3

在JavaScript方面,你。但是,實際上,JavaScript引擎本身可能會重新使用定義函數的代碼,並適當調整範圍以便重用。我讀過關於這種方法being used in Chromium

要僅使processor()訪問打印功能,你必須創建一個IIFE:

var out = document.getElementById("output"); 

var processor = (function() { 
    function print(msg) { 
     out.innerHTML += msg; 
    } 

    return function (n) { 
     while (n > 0) { 
      print(n--); 
      print(", "); 
     } 
     print("<br/>"); 
    }; 

}()); 

for (var i = 0; i < 10; i++) { 
    processor(i); 
} 

原因你重新創建這裏,而不是在循環的功能是因爲function (例如processor)定義了一個新的作用域,其中塊(循環等)不包含;函數聲明被提升到範圍的頂部,而不是