以前看了好多代碼,都有用到這種函數的寫法,可是都沒認真的去想爲何會這樣寫,今天開始想學習下jquery的源碼,發現jquery也是使用這種方式,用(function(window, undefined){})(window)包裹內部代碼,因而進一步的去學習了下。javascript
要理解當即執行函數(function(){})(),先了解些函數的基本概念(函數聲明、函數表達式、匿名函數)。java
函數聲明:使用function聲明函數,並指定函數名。 jquery
function setFn() { // coding }
函數表達式:使用function聲明函數,但未指定函數名,將匿名函數賦予一個變量。安全
var setFn = function() { // coding }
匿名函數:使用function關鍵字聲明函數,但未指定函數名。匿名函數屬於函數表達式,匿名函數有不少做用,賦予一個變量則建立函數,賦予一個事件則成爲事件處理程序或建立閉包等等。閉包
function() { // coding }
函數聲明與函數表達式的不一樣在於:函數
1. 函數聲明可在當前做用域下提早調用執行,函數表達式需等執行到該函數後,方可執行,不可提早調用。學習
setFn() function setFn() { // coding } // 正常,函數聲明可提早調用 setFn() var setFn = function() { // coding } // 報錯,setFn未保存對函數的引用,函數調用需放在函數表達式後面
2. 函數表達式可直接在函數後加括號調用。測試
var setFn = function() { console.log(2) }() // 2 解析至此,可直接執行調用
當即執行函數(function(){})()能夠看出很像函數表達式的調用,但爲何要加括號呢?若是不加括號:spa
function(){ console.log(1) }() // 報錯,函數須要函數名
解析: 雖然匿名函數屬於函數表達式,但未進行賦值,因此javascript解析時將開頭的function當作函數聲明,故報錯提示須要函數名
當即執行函數裏面的函數必須是函數表達式,因此由var setFn = function() {}()能夠理解爲在匿名函數前加了 = 運算符後,將函數聲明轉化爲函數表達式,因此拿!,+,-,()...等運算符來測試下是否如此。code
!function(){ console.log(1) }() // 1 +function(){ console.log(2) }() // 2 -function(){ console.log(3) }() // 3 (function(){ console.log(4) })() // 4
因而可知,加運算符確實可將函數聲明轉化爲函數表達式,而之因此使用括號,是由於括號相對其餘運算符會更安全,能夠減小沒必要要的麻煩。
當即執行函數與正常函數傳參形式是一致的。
(function(a, b){ console.log(a + b); })(1, 2) // 3
(function(){}())這樣寫的好處是在內部定義的變量不會跟外部的變量有衝突,達到保護內部變量的做用。