原文鏈接: 12 Simple (Yet Powerful) JavaScript Tips
其他鏈接: (譯文)12個簡單(但強大)的JavaScript技巧(一)
強大的立即調用函數表達式
(什么是立即調用函數表達式, 何時使用它)
IIFE (Immediately Invoked Function Expressions, 發音:“Iffy”)是立即調用函數表達式的縮寫形式, 它的語法大概如下:
(function() {
//Do fun stuff
})()
這是一個立即調用的匿名函數, 它在JavaScript中有一些特別重要的作用.
它是如何工作的?
-
包圍匿名函數的一對括號會把它變成函數表達式或者變量表達式.
-
這就相當於:
//不帶括號: ? = function() {}; //帶括號: (? = function() {}); //函數被一個不知名的變量引用了, 一對括號把它包圍了, 把它變成了一個匿名的函數表達式
同樣的, 我們甚至可以創建一個命名的立即調用函數表達式:
(showName = function(name) { console.log( name || "No Name"); })(); //No Name showName("Rich"); //Rich showName(); //NoName
-
記住, 當你不用var關鍵詞創建變量的時候, JavaScript會自動判斷該變量為全局變量. 在上面的例子中是沒有必要使用var關鍵詞的(因為你之后可能會調用它).
-
我們可以馬上或者在這之后使用這個函數
-
但是我們不可以在之后調用匿名函數. 因為除非你創建匿名函數之后馬上調用, 在這之后沒有其他辦法可以引用它. 這是匿名函數只可以馬上調用它的原因.
-
當把匿名函數包含在一對括號里面時(字面量), 整個字面量會被運算,並且返回匿名函數的返回值. 它的返回值實質上是整個匿名函數自身, 所以我們只需要在這之后加上一對括號來馬上調用它.
-
因此, 后面的一對括號等於告訴JavaScript編譯器馬上調用這個匿名函數, 所以它才會被稱之為"立即調用函數表達式".
-
因為JavaScript基於函數塊的作用域規則, 在匿名函數內聲明變量都是局部變量, 所以這些局部變量沒辦法直接從外部獲取.
-
就像其他函數一樣, 你可以向匿名函數設定參數和傳遞變量. 你可以根據這個特性, 利用匿名函數的作用域擴展它外圍函數的作用域(即閉包).
什么時候應該使用它?
-
避免污染全局作用域
IIFE最廣泛的用途是避免污染全局作用域. 已經有很多JavaScript庫和JavaScript高手正在使用這種技巧, 尤其是在最流行jQuery插件的開發者中. 你也應該把這個技巧應用在你的程序的主要文件中(main.js).
在這個例子中, 我使用了匿名函數把所有全局作用域的變量變成了局部變量, 所以現在全局作用域中還可以定義新的變量, 不用顧忌是否會和匿名函數內的變量在變量名上發生沖突(還包括其他庫或者框架):
//所有的代碼包含在立即調用函數中 (function() { var firstName = "Richard"; funtion init() { doStuff(firstName); //在這里開始插入應用程序的代碼... } function doStuff() { //... } function doMoreStuff() { //... } //啟動應用程序; init(); })();
-
用作條件選擇器
這種使用方式還沒有被廣泛所知, 但它是相當強大的. 你可以不調用一個命名函數來處理復雜的運算的. 注意在三目運算符(..
?
..:
.. )中的兩個匿名函數, 我盡可能多地加入空白來使語句看起來更容易理解:var unnamedDocs = [], namedDocs = ['a_bridge_runover', 'great_dreamers']; function createDoc(documentTitle) { var documentName = documentTitle ? (function(theName) { var newNamedDoc = theName.toLocaleLowerCase().replace('', '_'); nameDocs.push(newNamedDoc); return newNamedDoc; })(documentTitle) : (function() { var newUnnamedDoc = 'untitled_' + Number(namedDocs.length + 1); unnamedDocs.push(newUnnamedDoc); return newUnnamedDoc; })(); return documentName; } createDoc('Over The Rainbow'); //over_the rainbow createDoc(); //untitled_4