function(){}、var fun=function(){}和function fun(){}的區別
一、基本定義
1.函數聲明:使用function聲明函數,並指定函數名。
function fun() { // ...... }
2.函數表達式:使用function聲明函數,但未指定函數名,將匿名函數賦予一個變量。
var fun = function() { // ...... }
3.匿名函數:使用function聲明函數,但未指定函數名。匿名函數屬於函數表達式,匿名函數有很多作用,賦予一個變量則創建函數,賦予一個事件則成為事件處理程序或創建閉包等等。
function() { // ...... }
二、實例補充
1. 函數聲明可在當前作用域下提前調用執行,函數表達式需等執行到該函數後,方可執行,不可提前調用。
fun(); function fun() { // ...... } // 正確,函數聲明可提前調用
fun() var fun = function() { // ...... } // 錯誤,fun未保存對函數的引用,函數調用需放在函數表達式後面
2.函數表達式可直接在函數後加括號調用。
//傳統方法 var fun1 = function() { console.log(‘哈哈‘); } fun1(); //函數表達式後直接加括號調用 var fun2 = function() { console.log(‘哈哈‘); }()
3.立即執行函數(function(){})()的第一個小括號必須要加,因為如果不加第一個小括號的話,雖然匿名函數屬於函數表達式,但未進行賦值,所以javascript解析時將開頭的function當做函數聲明,故報錯提示需要函數名。加了第一個小括號,意思就是將函數聲明轉化為函數表達式。
//正確 (function(){ console.log(‘哈哈‘); })(); // 報錯 function(){ console.log(‘哈哈‘); }();
4.(function(){})()立即執行函數的註意點:在第一對括號內是一個匿名函數,第二個括號會立即調用這個匿名函數的返回值,也就是匿名函數中的內容被立即執行。這個玩意兒的強大之處在於它獨立了一個作用域(括號中內容執行完後會被立即回收),內部變量外部無法訪問,而它又能通過this保留字,來訪問外部變量。好處:內部定義的變量不會跟外部的變量有沖突,達到保護內部變量的作用。
三、JavaScript變量提升的概念
變量提升:函數聲明和變量聲明總是會被解釋器悄悄地被"提升"到方法體的最頂部。
1.變量可以在使用後聲明,也就是變量可以先使用再聲明。(因為函數聲明和變量聲明總是會被解釋器悄悄地被"提升"到方法體的最頂部)
x = 5; // 變量 x 設置為 5 console.log(x); //正常輸出5 var x; // 聲明 x var y; // 聲明 y y = 5; // 變量 y 設置為 5 console.log(y); //正常輸出5
2.JavaScript初始化不會提升。(JavaScript 只有聲明的變量會提升,初始化的不會。)
var x = 1; // 初始化 x var y = 2; // 初始化 y console.log(x); //正常輸出1 console.log(y); //正常輸出2 var a = 3; // 初始化 a console.log(a); //正常輸出3 console.log(b); //輸出undefined var b = 4; // 初始化 b
3.一個有趣的例子
var a = 1; //初始化a為1 var b = 2; //初始化b為2 var fun=function(){ console.log(a); //undefined var a = 22; console.log(b); //undefined var b; } fun();
為什麽會得到上述結果呢?原因如下:
JavaScript 只有聲明的變量會提升,初始化的不會。所以在function中,有var a = 22,這是初始化,變量的聲明會提升,但是變量的值沒有提升。有var b , 聲明的變量會提升到function最開頭,但因為沒有賦值,所以會輸出undefined。上述代碼等價於:
var a = 1; //初始化a為1 var b = 2; //初始化b為2 var fun=function(){ var a; var b; console.log(a); //undefined a = 22; console.log(b); //undefined } fun();
4.另一個有趣的例子
var a = 1; //初始化a為1 (function(){ a=3; console.log(a); //3 var a; })(); (function(){ console.log(this.a); //1 })(); var fun=function(){ console.log(this.a); //1 } fun();
關鍵:立即執行函數、函數表達式和函數聲明能通過this保留字,來訪問外部變量。
當然如果function函數內部沒有聲明外部已有變量的話,function函數內部可直接使用外部已有變量,不使用this保留字也是可以的。(函數聲明、函數表達式、立即執行函數結果都是這樣,原因應該是當在function函數內部沒有找到定義的變量時,會自動擴大作用域,向上搜索給出的變量)
var a = 1; //初始化a為1 (function(){ console.log(a); //1 })(); var fun=function(){ console.log(a); //1 } fun();
function(){}、var fun=function(){}和function fun(){}的區別