函數有很多種,我們就選擇我們不懂的函數開始學習!
JS中自動運行的匿名函數
在JavaScript中可以使用匿名函數(在我們學習Java的時候也有類似的概念,匿名實現類),在JavaScript中的函數也是一種對象,也是需要一塊內存對其進行保存。如果想調用該函數,我們只是需要找到這塊內存即可,然後就可以執行。關鍵步驟如下:
- 將函數對象保存到一塊內存當中
- 找到這塊內存
通常我們使用函數名來查找這塊地址,不過通過函數名只是找到這塊內存地址的一種工具而已。
function test01(){
console.log("定義方式");
}
//函數的調用
test01();
var test02 = function () {
console.log("變量方式");
}
//函數的調用
test02();
上述的示例,我們就是通過函數名找到了這塊內存地址,在使用()進行函數的執行,也就是隻要我們能找到這塊內存就可以去執行!
匿名函數,顧名思義就是沒有名字的函數,其實在上面寫的test02函數表達式中,我們就創建了匿名函數,並將該函數賦值給了變量test02,用test02來進行函數的調用,調用方式就是在變量test02後面加入小括號,這是匿名函數的調用方式之一
還有一種匿名函數的調用規則如下:
- 第一步:使用function關鍵字定義一個函數
-
第二步:使用小括號將內容括起來
關鍵步驟:這只是一種語法的要求,否則後面的執行語句無法被引擎正確的識別,如果這樣將函數定義好,引擎就會為其分配一塊內存保存
- 第三步:直接在後面加入小括號完成調用,可以放入參數
(function (x, y) {
console.log(x+y);
})(2, 3);
//等價於代碼
var test03 = function(x,y){
console.log(x+y);
}(2,3);
代碼分析
var log=(function(){
console.log("創建日誌函數");
return function(param){
console.log(param);
};
})();
log("www.baidu.com");
這段代碼屬於一種比較經典的代碼,這裏創建了一個自動運行的匿名函數,不過其返回值仍然是一個匿名函數,也就是説函數自運行後返回的結果仍然是函數。把返回值的函數賦值給變量log,就可以使用log變量來調用返回的函數了。
請注意上述代碼中,我們其實是包含兩塊內存保存函數,自動運行的函數本身有一塊內存來保存,當碰到後面表示執行的小括號後會自動運行,另外還有一塊內存來保存所返回的函數,而返回的值其實是這塊內存地址,這樣log變量就指向了這塊保存函數的內存,因此可以使用log來完成對函數的執行。
一些有趣的自運行函數的定義方式
// 下面2個括弧()都會立即執行
(function () { /* code */ } ()) // 推薦使用這個
(function () { /* code */ })() // 但是這個也是可以用的
// 由於括弧()和JS的&&,異或,逗號等操作符是在函數表達式和函數聲明上消除歧義的
// 所以一旦解析器知道其中一個已經是表達式了,其它的也都默認為表達式了
var i = function () { return 10; } ();
true && function () { /* code */ } ();
0, function () { /* code */ } ();
// 如果你不在意返回值,或者不怕難以閲讀
// 你甚至可以在function前面加一元操作符號
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();
// 還有一個情況,使用new關鍵字,也可以用,但我不確定它的效率
// http://twitter.com/kuvos/status/18209252090847232
new function () { /* code */ }
new function () { /* code */ } () // 如果需要傳遞參數,只需要加上括弧()
void function(){ /* code */ }();