2013-01-18 55 views
4

我見過寫自調用函數的下一個方法:自調函數和參數?

(function (app) { 
    app.foo = { 
     bar: function(){} 
    }; 
}(App)); 

App是一個全局對象。

我想知道,爲什麼我們需要將App作爲參數傳遞給函數?爲什麼不用這個:

(function() { 
    App.foo = { 
     bar: function(){} 
    }; 
}()); 

我看到使用第一種方法只有一個優點。如果我們由於某種原因重命名App對象,那麼我們可以輕鬆地重命名括號中的參數,我們的代碼將在工作時起作用。但在第二種情況下,我們可能需要在我們使用它的所有地方重命名App

還有其他的區別嗎?

回答

9

這意味着該函數的內容 - 關於app標識符 - 對於全局(或父)範圍是不可知的。

例如,在jQuery中,當你不想假定jQuery對象被調用$(例如,如果沒有衝突模式打開),但是你的想要通過該名稱進行調用。通過像這樣的匿名函數(即(function($) {})(jQuery))傳遞它,可以生成不影響父/全局範圍中名稱$的外部含義的本地範圍別名。

1

例如,許多庫使用「$」字符作爲其主函數(例如JQuery)的快捷方式。這很方便,但是在使用多個庫時會引起衝突。所以,你可以像這樣通過JQuery

(function($) { 
    // Code 
    var nav = $('#nav'); 
    // More code 
})(JQuery); 

這樣的話,你仍然可以使用的方便快捷,但你也能避免發生衝突(只要你還沒有配置庫使用「$」捷徑)。

2

其他答案解釋了具有本地作用域副本的好處。還有其他一些好處:

  • 作爲一種微型優化,它減少了範圍查找(找到局部變量比全局變量更便宜)。
  • 它可以在縮小過程中提供幫助,因爲所有參數都縮減爲名爲變量的單個字母。
  • 它給你一個僞依賴管理技術......在你的例子中,你知道你的代碼依賴於App
+0

+1對於一個很好的補充答案 –

1

你也可以用它來重新定義本地全局變量,以確保它們包含whay你期望:

(function($, undefined) { ... })(jQuery); 

哪裏undefined現在預期的不確定。另請參閱:What is the purpose of passing-in undefined?

大多數其他用途在其他答案中都有很好的介紹。