1. 程式人生 > >function(){}、var fun=function(){}和function fun(){}的區別

function(){}、var fun=function(){}和function fun(){}的區別

定義 () 屬於 方法體 獨立 又能 找到 nbsp 保留

一、基本定義

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(){}的區別