1. 程式人生 > >Web前端面試筆試題2——JS(1):函式呼叫(區域性變數/全域性變數)

Web前端面試筆試題2——JS(1):函式呼叫(區域性變數/全域性變數)

1、函式呼叫——區域性變數/全域性變數

案例1-1:fun(a)函式有傳參,即可更改“區域性變數”

var a=100;
function fun(a){
     a++;
     console.log(a);
}
fun(100);//101;
console.log(a);//100

解析:在上述案例中,由於函式fun()中傳入引數“a”,所以a=100,進行了函式賦值,“a++”之後,a由“100”變成了“101”;再經過“fun(a)”,輸出“101”,fun(100)返回“101”。

但是,對於fun(a)而言,“a++”後“a=101”,作為一個區域性變數,在程式執行完畢就被銷燬,所以在外部函式而言,“a= ”全域性變數“a(100)”,所以“console.log(a)”,輸出“100”。

window
a 100
fun(函式物件) console.log(a)
拓展—— 如果將函式fun(a)改為“fun()”,表示函式沒有區域性變數,即設定了“無參”模式,自身沒有傳遞“區域性變數”,所以經過“a++”之後,更改完即更改全域性變數。 案例1-2:fun()沒有傳遞引數,即為“全域性變數”
var a=100;
function fun(){
    a++;
    console.log(a);
}

fun(100);    //101
console.log(a);    //101

解析:
在上述案例中,唯一不同的就是“fun(a)”改為“fun()”,即“fun()”不傳入引數,裡邊的引數即為傳遞“全域性變數”,所以“a++”之後,更改的是“全域性變數a”;
但是,案例1-1中“fun(a)”中,即“fun(a)”傳入引數,裡邊的引數即為傳遞“區域性變數”,當函式fun()執行完畢後,區域性變數即刻銷燬,所以“console.log(a)”還是“全域性變數”,這亦是兩個案例的不同之處所在。 2、給未宣告的變數賦值,系統會自動定義宣告 案例2-1:
var n=101;
function foo(){
    m=100;
    console.log(m);
}
foo();              //100
console.log(m);     //100
解析: 在上述案例中,由於“fun()”表示“無主語”狀態,即表示全域性變數,所說外部僅有全域性變數“n”,但是在fun()函式中,“m=100”,變數宣告,所說外部僅定義全域性變數“n”,並未定義“m”。但是,系統會自動定義“m”,此時“m”為“全域性變數”。

案例2-2:
function foo(m){
    m=100;
    console.log(m);
}
foo();              //100
console.log(m);     //會報錯!
解析: 在上述案例中,與“案例2-1”不同的是。foo(m)傳入了引數“m”,此時“m”不再是“foo()”中的為“全域性變數”,此時是“區域性變數”。 根據區域性變數特點“執行完畢即被銷燬”,所以,執行完“foo()”函式後,區域性變數“m”即刻消失,所以“console.log(m)”即會報錯! 總結—— (1)若函式傳遞引數,如“fun(a)”,此時函式內部“a”,即為區域性變數,外部為“全域性變數”。 (2)區域性變數“a”僅在區域性函式“fun(a)”呼叫執行時被使用,執行完畢後,區域性變數“a”將被銷燬。 (3)若在函式fun()未傳遞引數,即為“全域性變數”。若聲明瞭未被定義的變數,此時的變數系統會自動定義該變數,為“全域性變數”。 (4)若在函式fun()中傳遞引數fun(m),此時只執行函式內部,執行完畢即銷燬,“console.log(m)”將會報錯顯示。 3、區域性變數+全域性變數“混合” 案例3-1:
var a=100;
function fun(){
    console.log(a);
    var a=90;
    console.log(a);
}
fun();//undefined  90
console.log(a);         //100

解析:
由於在區域性變數中,並未定義變數“a”,所以此時a為“未定義undefined”狀態; 後來又重新賦值“90”,此時函式輸出“90”,“a=90”作為“區域性變數”,執行完畢即被銷燬。 但是,外部全域性變數並不會改變,還是“a=100”。 案例3-2:
var a=100;
function fun(){
    console.log(a);
    a=90;
    console.log(a);
}
fun();//100  90
console.log(a);         //90
解析: 由於與“案例3-1”相比,“var a=90”取消了“var”,此時“無var,有賦值”,“a”為全域性變數二次賦值,此時“a=90”。 但是,起始的“a=100”由於重新賦值,所以“a=90” 4、函式重複宣告、呼叫
function foo(){
   return 1;
}
console.log(foo());       //1

function foo(){
   trturn 2;
}
console.log(foo());      //2

var foo=100;
console.log(foo());      //“出錯”

解析:
由於上述案例中,前兩個均為“宣告提前”,但是第三個中,宣告“var  foo=100”,此時的foo為一個變數,而不是一個函式型別,所以當“console.log(foo())”時,會出錯。