fb-script

2015年10月2日 星期五

javascript 中的匿名函式初始化 (function(){})() 是什麼意思

先來看看 function 的宣告不同的地方

  1. function funcA() {}
  2. var funcA = function(){}

這兩種基本上是一樣的,差異在於,第二種寫法是變數寫法,所以在宣告前使用會出現尚未宣告的錯誤,意思這樣

funcB(); //使用 funcB
var funcB = function(){}; // 宣告 funcB,因為是變數所以需要加分號結尾。

這樣的用法會出現 Uncaught TypeError: funcB is not a function

如果是使用第一種寫法

funcC(); // 使用 funcC
function funcC(){} // 宣告一個 function 叫做 funcC

像這樣用法就不會出錯誤

這是因為兩者的定義時間不同,funcB 是在宣告時才定義,而 funcC 在編譯<script></script>區塊的時候就定義了

好,所以當希望頁面一直行就先執行某個 function 了話,就以上方法會這樣做

function funcD(){} // 宣告 funcD,用此宣告方式,放在前或後都無所謂。
funcD(); // 執行 funcD

而因為 javascript 支援匿名函式,所以如果把 funcD 的內容直接寫在執行的時候也是可以的,就會變成這樣

(function(){
 // funcD 的內容
})();// 執行匿名 function

這就是匿名初始化的原型,那如果想在匿名函式庫裡面傳送參數呢?就是這樣啦

(function(arg){ // 宣告此匿名 function 會接一個引數
// function 內容
})(100); // 使用此 function 並將 100 當參數帶入。

將這樣的格式轉成上述的 funcD 的例子了話就是

function funcD(arg) {}
funcD(100);

所以匿名函式庫也能傳送參數,這樣的用法在很多地方都常常使用,例如想要自訂 jQuery 的函式庫,網路上教學都是寫這樣

(function($){
$.fn.extension = ...
$.extension = ...
})($);

為什麼是這樣呢?經過上面的解釋就可以發現,其實他是匿名函式的寫法,把 $ 傳入當參數,因為先導入了 jQuery 的 lib,所以 $ 就等於 jQuery 這個 javascript 的物件,利用 js 物件的特性,在 $ 上加入想要的東西,就變成自訂 jQuery plugin 啦

另外也可以用這種方法來定義客製化物件型別,例如

(function(exports){
function User(id,name) { // 宣告一個物件類別。
this.id = id;
this.name = name;
}
exports.User = User; // 將這物件類別加入到 window 全域物件中。
})(window);

這就是把 window 這個全域物件當參數傳入,然後將自訂的物件類型加到裡面,這樣在任何地方都可以使用這樣的類別

當然也可以做一個全域物件讓所有地方使用,繼上面的例子

(function(exports){
var user1 = new User(123,'Johhny'); // 因為之前已經宣告了 User 類型,所以可以直接使用。
exports.user1 = user1; // 將 user1 這個物件綁到 window 全域物件中。
})(window);

這樣的做法就是有一個 user1 的 User 型別物件會在 window 中找得到

沒有留言:

張貼留言