JavaScript變量的做用域

    雖然《JavaScript權威指南》這本書很好,可是有一些東西讓人容易理解錯。最近在惡補基礎,結合這本書,我想把變量的做用域從新梳理一下:java

    "一個變量的做用域(scope)是程序源代碼中定義這個變量的區域。全局變量擁有全局做用域,在JavaScript代碼中的任何地方都是有定義的。然而在函數內聲明的變量只在函數體內有定義。"----摘自《JavaScript權威指南》第6版es6


     "在一些相似C語言的編程語言中,花括號內的每一段代碼都具備各自的做用域,並且變量在聲明他們的代碼段以外是不可見的,咱們稱之爲塊級做用域。"----摘自《JavaScript權威指南》第6版編程


    在ECMAScript 6以前是沒有塊級做用域的,這裏說的是ECMAScript5.1規範標準。閉包

    變量分全局變量,局部變量。這就決定了變量的做用域:全局做用域、與函數做用域編程語言

demo1:函數

var scope = "global"; //聲明一個全局變量
function check() {    
    var scope = "local";    //聲明一個同名的局部變量
    return scope;        //返回局部變量的值,而不是全局變量的值
}
check();        => "local"

解:spa

    " 在函數體內,局部變量的優先級高於同名的全局變量。若是在函數內聲明的一個局部變量or函數參數中帶有的變量和全局變量重名,那麼全局變量就會被局部變量所遮蓋。"----摘自《JavaScript權威指南》第6版code

實踐證實:orm

var scope = "global"; //聲明一個全局變量
function check() {    
    var scope = "local";    //聲明一個同名的局部變量
    return scope;        //返回局部變量的值,而不是全局變量的值
}
check();        => "local"
console.log(scope);      =>"blobal"

    書上的話容易誤導人,不少人一開始把這裏的"遮蓋"當成了覆蓋,想固然認爲全局變量scope的值變成了"local",實則否則。 在函數體內,局部變量的優先級高於同名的全局變量。其實check函數返回就是局部變量scope,而不是全局變scope;二者只是同名而已。
對象


demo2:

scope = "global"; //聲明一個全局變量,不使用var聲明
function t() {    
    scope = "local";    //修改了全局變量
    myscope = "local;    //聲明一個新的全局變量
    return [scope,myscope];        //返回兩個值
}
t();        scope => "local"    myscope => "local" //二者都爲 "local"

解:

    在js中,若是給一個沒有聲明的變量賦值,都是全局變量,並且是全局對象的屬性。


demo3:

var scope="global";  //聲明一個全局變量
function t(){  
    console.log(scope);  
    var scope="local"  
    console.log(scope);  
}  
t();     scope => 第一次爲 undefined      第二次才爲 "local"

解:

       不少人勿認爲第一次打印的是全局變量,其實否則。 js函數做用域:指在函數內聲明的全部變量在函數體內始終是可見的。有意思的是,這意味着變量在聲明以前甚至已經可用。js這個特性被非正式地成爲聲明提早。即:js函數裏聲明的全部變量都(不涉及賦值)被「提早」到函數體的頂部。

    上述過程等價:將函數內的變量聲明「提早」至函數體頂部,變量初始化留在原來的位置。等價於以下的代碼:

var scope="global";  //聲明一個全局變量
function t(){  
    var scope;    //頂部聲明瞭局部變量
    console.log(scope);  //變量存在,但未初始化
    scope="local"     //初始化並賦值
    console.log(scope);  
}  
t();


函數內聲明的變量都是局部變量,函數外是沒法訪問的,外部想要訪問函數內的變量能夠採用閉包來實現,代碼實例以下:

demo4:

function t (){
    var x=10;
    return function () {
        return x;
    }
}
console.log(x);    //報錯,x未定義
var a = t();
console.log(a());    //10


在js編寫當中,因爲規範太少,寫法靈活,可能致使出現各類bug。聲明變量時,最好放在函數體頂部,增長易讀性。

es6中,增長了不少特性,js的規範愈來愈標準化,已成爲一門通吃各個平臺的語言,加油!

相關文章
相關標籤/搜索