JS的作用域問題
阿新 • • 發佈:2018-11-21
一、塊級作用域
在 JavaScript 中, 作用域為可訪問變數,物件,函式的集合。
js沒有塊級作用域(你可以自己閉包或其他方法實現),只有函式級作用域,函式外面的變數函式裡面可以找到,函式裡面的變數外面找不到。
var a=10;
function aaa(){
alert(a);
};
function bbb(){
var a=20;
aaa();
}
bbb(); //結果為10,因為aaa()函式不能訪問到bbb()裡面的區域性變數,所以訪問到的是a=10,這個全域性變數。
二、全域性變數
變數在函式外定義,即為全域性變數。
全域性變數有 全域性作用域
當函式被定義時,函式物件內部不僅包含了程式碼邏輯,還定義了一個內部屬性[[Scope]]引用了一條作用域鏈(可以理解成為一個物件列表)。如果這個函式在全域性環境下被定義,那這個作用域鏈裡就只有全域性作用域。
var a=10;
function aaa(){
alert(a);
};
aaa(); //a 為外部變數即全域性變數,所以可以直接訪問到 結果為10
不用var 定義變數時,會預設為是全域性變數(不規範,不推薦)
function aaa(){ a=10; } aaa(); alert(a); //結果為10; //等價於: var a; function aaa(){ a=10; }; aaa(); alert(a);
給未宣告的變數賦值時,此變數就會變成全域性變數。例如:var a=b=10; 可以解析成 b=10;var a=b; 也就是b為全域性變數,a為區域性變數,所以外部訪問a訪問不到,訪問b結果為10;所以為了避免出現這種隱患,我們在定義變數的時候把所有要定義的變數都加上var。
function aaa(){
var a=b=10;
}
aaa();
alert(a);//結果為,無法訪問到
alert(b);//結果為10;
變數的查詢是就近原則,去尋找var定義的變數,當就近沒有找到的時候就去查詢外層;第二點,變數的宣告被提前到作用域頂部,賦值保留在原地,如下示例:
function aaa(){
alert(a);
var a=20;
}
aaa(); //結果為:undefined
/**************/
var a=10;
function aaa(){
alert(a);
var a=20;
}
aaa(); //結果為:undefined
可以解析為是:
var a=10;
function aaa(){
var a; //宣告提前了
alert(a);
a=20; //賦值扔留著原地
}
aaa();
三、區域性變數
變數在函式內宣告,變數為區域性作用域。
區域性變數:只能在函式內部訪問。
因為區域性變數只作用於函式內,所以不同的函式可以使用相同名稱的變數。
區域性變數在函式開始執行時建立,函式執行完後區域性變數會自動銷燬。
function aaa(){
var a=10;
};
aaa();
alert(a); //a 為函式aaa()內部變數量即區域性變數,所以無法訪問到
當引數跟區域性變數重名的時候,優先順序是等同的。
var a=10;
function aaa(a){
alert(a);
var a=20; //因為 a 是形參,優先順序高於 var a; 所以 區域性變數a的宣告其實被忽略了。
}
aaa(a); //結果為:10
變數修改的時候另一個變數會跟著變化,但是當變數重新被定義時,則另一個不變化。
var a=[1,2,3];
var b=a;
b.push(4);
alert(a);//結果為[1,2,3,4] 當b改變的時候a也發生了改變
當b重新被賦值的時候 a不會改變.示例:
var a=[1,2,3];
var b=a;
b=[1,2,3,4]
alert(a)//結果為[1,2,3]