立即執行函數 (Immediately Invoked Function Expression,簡稱 IIFE) 顧名思義,就是一定義完馬上就執行的函式。
使用方法
最常見的使用方法有兩種,將原本的函式用()包起來,在最後或{}後加上()就會立刻執行裡面的函式。兩個功能一樣,選一個喜歡的用就好。
(function () {
// 會立刻執行此處程式碼
}());
(function () {
// 會立刻執行此處程式碼
})();
也可以使用 arrow function 的版本。(但不建議這麼做,function 開頭的可讀性較高)
(() => {
var aName = "Barry";
})()
和一般函式一樣可以有返回值:
var result = (function () {
var name = "Barry";
return name;
})();
// Immediately creates the output:
result; // "Barry"
和一般函式一樣可以帶入參數:
(function (w, d, $) {
// w 是一個局部變數,指向 window 物件
// d 是一個局部變數,指向 document 物件
// $ 是一個局部變數,指向 jQuery 物件
}(window, document, jQuery));
也可以使用實名的IIFE,效果和用法是一樣的。
(function iife() {
// ...
})();
有時你也會看到前面加一個分號';',這是一個防禦型分號,用於兩個JS檔案合併時可能會產生的問題。
;(function() {
// ...
})();
例如:
var foo = bar
(function() {
// ...
})();
看起來像一個賦值和一個IFEE,但是事與願違,沒有加上分號的話,會被解析成bar
被當作一個接受參數為函式類型的函式了。
var foo = bar(function() {
// ...
})();
IIFE特性
最常用的IFEE特性之一為變數為私有狀態,意即全域變數命名空間不會被污染。
(function () {
var aName = "Barry";
})();
console.log(aName) // aName is not defined
我們看一題常見的面試考題:
var myObject = {
foo: "bar",
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
(function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
}());
}
};
myObject.func();
融合我們之前學過的this
指向,大家先想一下。
在 outer 函式中,this
指向 myObject。
但在 inner 函式中,第一個 console 由 IIFE 包著,有著自己的作用域,因此 this
不指定的情況下會指向 window
(嚴格模式會是undefined
。)
self
則參考外層變數,指向了外層的 this
。
所以我們會得到
outer func: this.foo = bar
outer func: self.foo = bar
inner func: this.foo = undefined
inner func: self.foo = bar
ps:雖然轉職成為前端已經快一年了,但我還沒實際應用過 IIFE 呢!