Javascript中的範圍(scope)

來源:互聯網
上載者:User

類 C 語言一般都用於塊級範圍,但是Javascript中的 while, if-else, for, switch-case 等控制結構不具有自己的範圍,

在Javascript中只有函數(function)具有自己的範圍,請比較如下的 C# 代碼和 Javascript 代碼:

// C# 中 for 迴圈有自己的範圍
for (int i = 0; i < 5; i++)
{
    //
}
Console.WriteLine(i); // 當前上下文中不存在名稱“i”

 

// Javascript中 for 迴圈沒有自己的範圍
for (var i = 0; i < 5; i++) {
    // do something
}
console.log(i);   // 5

但是,Javascript中的函數有自己的範圍,如下樣本:

// function 擁有自己的範圍
(function() {
    var j = 6;
})();
console.log(typeof (j)); // 'undefined'

 

// function 中使用和全域變數相同名稱的局部變數
var i = 5;
(function() {
    var i = 1;
})();
console.log(i);   // 5

 

在函數中不使用 var 關鍵字聲明的變數,就會在全域範圍內尋找,如下:

var i = 5;
(function() {
    i++;    // 此時的i是全域變數
})();
console.log(i);   // 6

 

這裡就有一個可能讓人迷惑的代碼,如下:

var i = 6;
(function() {
    i++;    // 此時的i是局部變數,但是未定義(undefined),undefined + 1 == NaN
    console.log(isNaN(i));    // true
    var i;
})();
console.log(i);   // 6

或許你會覺得函數中 i++, 引用的豈不是全部變數?

答案是否定的,只要在函數內擁有相同名稱的局部變數定義,那這個變數就是局部的。

那我們如何在函數內引用和局部變數相同名稱的全域變數呢?

答案是使用命名首碼。考慮如下代碼:

 

var i = 6;
(function() {
    window.i++;    // 此時的i是局部變數
    var i = 1;
})();
console.log(i);   // 7


正因為自執行的匿名函數,可以用來向外部隱藏屬性,我們可以用這個特性在Javascript中實現私人屬性。

 

考慮如下擷取隨機數([0,10])的對象:

 

var random1 = {
    _num: -1,
    _init: function() {
        // 隨機一個大於等於0,小於等於10的整數
        this._num = Math.round(Math.random() * 10);
    },
    getNum: function() {
        if (this._num === -1) {
            this._init();
        }
        return this._num;
    }
};
console.log('random1._num == ' + random1._num); // -1
console.log('random1.getNum() == ' + random1.getNum()); // [0,10]


雖然我們的意圖是想向外界隱藏 _num 變數和 _init 屬性,不過這個目的顯然沒有達到,使用者仍然可以通過 random1._init(); 的方式調用。

 

我們需要是用Javascript中函數特有的性質(擁有自己的範圍),使用自執行的匿名函數來達到隱藏屬性的目的。

考慮如下解決辦法:

 

var random2 = {};
(function() {
    var _num = -1;

    function _init() {
        _num = Math.round(Math.random() * 10);
    }

    random2.getNum = function() {
        if (_num === -1) {
            _init();
        }
        return _num;
    };
})();
console.log('random2._num == ' + random2._num); // 'undefined'
console.log('random2.getNum() == ' + random2.getNum()); // [0,10]

 


代碼下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.