JavaScript的詞法作用域

<JavaScript權威指南>中,對於JS詞法作用域的描述是:

JavaScript中的函數是通過詞法來劃分作用域的,而不是動態地劃分作用域的.這意味著,它們在定義它們的作用域裡運行,而不是在執行它們的作用域裡運行.

咋看之下貌似明白瞭,但細想一下,又貌似有點含糊.

還是用例子來顯示一下吧.

[javascript]
var i = 1; 
function a() { 
    alert(i); // 1  

a();  
var i = 1;
function a() {
    alert(i); // 1
}
a(); 

上面,變量 i 就是一個全局變量,它的作用域就是整個js文件.

其實,我們可以把上面的代碼,理解為一個全局的函數,如下:

[javascript]
(function () { 
    var i = 1; 
    function a() { 
        alert(i); // 1  
    } 
    a();  
})(); 
(function () {
    var i = 1;
    function a() {
        alert(i); // 1
    }
    a();
})();

 

這樣並沒有體現出JS詞法作用域的特別之處;

 

我們來看看下面的代碼:

[javascript]
(function () { 
    var i = 1; 
    function a() { 
        alert(i); // undefined  
        var i = 2; 
        alert(i); // 2  
    } 
    a();  
})(); 
(function () {
    var i = 1;
    function a() {
        alert(i); // undefined
        var i = 2;
        alert(i); // 2
    }
    a();
})();令人意外的,第一個彈出的警告居然不是1,而是undefined.
這顯然有點不可思議.

 

其實這就是所謂的:它們在定義它們的作用域裡運行,而不是在執行它們的作用域裡運行.

因為在定義函數 a() 的時候定義瞭 var i = 2 ;這樣函數 a() 中所調用的變量 i 的作用域隻限於函數 a() 裡面的.

當調用函數時,第一個 alert(i) 觸發的時候,變量 i 還沒有定義,所以彈出undefined的警告,

而當第二個 alert(i) 觸發時, 變量 i 已經被賦值為2.

 

 

代碼其實和下面的等價:

[javascript]
(function () { 
    var i = 1; 
    function a() { 
        var i; 
        alert(i); 
        i = 2; 
        alert(i); 
    } 
    a();  
})(); 
(function () {
    var i = 1;
    function a() {
        var i;
        alert(i);
        i = 2;
        alert(i);
    }
    a();
})();

 

這就是所謂的:  在定義函數的時候, 變量的作用域已經劃分好瞭.

 摘自 簡生的代碼備忘錄
 

發佈留言