1. 程式人生 > >JS的作用域問題

JS的作用域問題

一、塊級作用域

在 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]