JavaScript 變量做用域

一. 變量聲明

變量用var關鍵字來聲明,以下所示:javascript

var num;
var a,b;
var name = "ting";
var i=0, j=1, k=2;

用var關鍵字申明的變量是永久的,用delete運算符刪除不起做用。html

var i = 2;
delete i;
console.log(i);   // 2

k = 3;
delete k;
console.log(k);  // 報錯:ReferenceError: k is not defined.

JavaScript變量是鬆散類型的,能夠用來保存任何數據類型。而且還可在修改變量的值時改變變量的類型。前端

var answer = 10;
answer = "The answer is: " + 10;
console.log(answer);                 // 10
console.log( typeof answer);          // string

 

二. 變量做用域

變量的做用域是程序中定義這個變量的區域。函數內部聲明的變量只在函數內部起做用。聲明局部變量必定要使用var關鍵字聲明。java

在函數內部,局部變量做用域高於同名全局變量。segmentfault

var i = 99;
function foo() {
     var i = 100;
    console.log(i);   // 100(使用局部變量)
}
foo();
console.log(i);       // 99(使用全局變量)

聲明局部變量未使用var關鍵字,該變量會暴露在全局環境中,與現有的全局變量衝突。以下代碼中,函數內部的變量a未使用var關鍵字,與全局環境中的a衝突,在全局環境中調用a。函數

var a = 5;
function foo() {
    a = 10;
    b = 15;
    console.log(a);   // 10
    console.log(b);   // 15
}
foo();
console.log(a);       // 10
console.log(b);       // 15

變量在未聲明的狀況下被初始化,會被添加到全局環境。spa

var add =  function(a,b) {
     var sum = a + b;
     return sum;
}
var res = add(2,3);
console.log(res);        // 5
console.log(sum);        // ReferenceError: sum is not defined

var add =  function(a,b) {
    sum = a + b;
     return sum;
}
var res = add(2,3);
console.log(sum);        // 5

JavaScript執行代碼時,會建立一個上下文執行環境,全局環境是最外圍的環境。每一個函數在被調用時都會建立本身的執行環境,當函數執行完,當前執行環境被銷燬。code

每一個執行環境都有一個與之關聯的做用域鏈。在執行代碼時,JavaScript引擎會經過搜索執行環境的做用域鏈來解析變量和函數名這樣的標識符。 解析過程從做用域鏈的前端開始,向上逐級查詢與給定名字匹配的標識符,一旦找到標識符,搜索過程就中止,不然繼續沿做用域鏈向上搜索,一直搜索到全局對象。若是沒有搜到,則認爲該標識符未定義。標識符在做用域鏈中的位置越深,查找和訪問它的時間越長,因此儘量使用局部變量。htm

全局環境只能訪問在全局環境中定義的變量和函數,不能直接訪問局部環境中的任何數據。對象

 

三.  沒有塊級做用域

JavaScript中沒有塊級做用域,舉個例子。若是JavaScript中有塊級做用域的話,控制檯輸出的應該是undefined。但實際上控制檯輸出的是100,這是爲何呢? 緣由在於:沒有塊級做用域,變量i沒有被銷燬,所以還能訪問到這個變量。

for( var i=0; i<100; i++) {
     // todo
}
console.log(i);    // 100

JavaScript中存在函數做用域。當foo函數執行完畢後,函數內的變量將被銷燬,所以控制檯報錯。

function foo() {
     var bar = "fn";
}
foo();
console.log(bar);   // 報錯:ReferenceError: bar is not defined.

函數做用域模擬塊級做用域。

( function() {
     for( var i=0; i<100; i++) {
         // todo
    }
})();
console.log(i);    //報錯:ReferenceError: bar is not defined.

再看一例:局部變量a在整個foo函數內部都有定義的,隱藏了全局變量a。但第一個console在變量初始化以前,因此其值爲undefined。

var a = 8;
var foo =  function() {
    console.log(a);      // undefined
     var a = 5;
    console.log(a);      // 5
};
foo();


四. 未賦值的變量和未定義的變量

未賦值的變量值爲undefined,而使用未定義的變量會引發錯誤。

var a;
console.log(a);   // undefined
console.log(b);   // ReferenceError: b is not defined


五. 垃圾收集(garbage collection)

JavaScript具備自動垃圾收集機制,Javascript解釋器能夠檢測到什麼時候程序再也不使用一個對象,就把它所佔用的內存釋放。

 

 

 

時間:2014-10-22

地點:合肥

引用:http://wlog.cn/javascript/javascript-variable-scope-chain.html 

        http://segmentfault.com/blog/liangyi/1190000000692129

相關文章
相關標籤/搜索