變量的類型和做用域

1、變量的類型
JS是一種無類型、弱檢測的語言。它對變量的定義並不須要聲明變量類型,咱們只要經過賦值的形式,能夠將各類類型的數據賦值給同一個變量。例如:
i=100;//Number類型
i="variable";//String類型
i={x:4};//Object類型
i=[1,2,3];//Array類型
2、變量的聲明
JS中變量申明分顯式申明(局部變量)和隱式申明(全局變量)。
var i=100;//顯式申明
i=100;//隱式申明

在函數中使用var關鍵字進行顯式申明的變量是作爲局部變量,而沒有用var關鍵字,使用直接賦值方式聲明的是全局變量。
注意:當咱們使用或訪問一個沒有聲明的變量時,JS會報錯。而當咱們給一個沒有聲明的變量賦值時,JS不會報錯,相反它會認爲咱們是要隱式申明一個全局變量。
3、全局變量和局部變量
當JS解析器執行時,首先就會在執行環境裏構建一個全局對象,咱們定義的全局屬性就是作爲該對象的屬性讀取,在頂層代碼中咱們使用this關鍵字和window對象均可以訪問到它。
而函數體中的局部變量只在函數執行時生成的調用對象中存在,函數執行完畢時局部變量即刻銷燬。
所以在程序設計中咱們須要考慮如何合理聲明變量,這樣既減少了沒必要要的內存開銷,同時能很大程度地避免變量重複定義而覆蓋先前定義的變量所形成的Debug麻煩。
4、變量做用域
JS中變量的做用域,一個很大的特徵就是JS變量沒有塊級做用域,函數中的變量在整個函數都中有效,運行下面代碼1:
function outPut(s){
    document.writeln(s)
}
var i=0;//全局變量
//定義外部函數
function outer(){
    outPut(i); //訪問全局變量 0
    //定義一個內部函數
    function inner(){
        var i = 1;//顯示申明 定義局部變量
//        i=1; //若是用隱式申明 那麼就覆蓋了全局變量i
        outPut(i); //訪問局部變量 1
    }
    inner();
    outPut(i); //訪問全局變量 0
}
outer();
輸出結果爲0 1 0,從上面就能夠證實JS若是用var在函數體中聲明變量,那麼此變量在且只在該函數體內有效,函數運行結束時,局部變量即刻銷燬了。
運行下面代碼2:
function outPut(s){
    document.writeln(s)
}
var i=0;//全局變量
//定義外部函數
function outer(){
    outPut(i); //訪問全局變量 0
    //定義一個內部函數
    function inner(){
        outPut(i); //undefined
        var i = 1;//顯示申明 定義局部變量
        outPut(i); //訪問局部變量 1
    }
    inner();
    outPut(i); //訪問全局變量 0
}
outer();
輸出結果是0 undefined 1 0,由於JS函數體中聲明的局部變量在整個函數中都有效,所以在上面代碼中var i = 1 ;在inner函數中都有效,實際上顯式聲明的變量i是在預編譯時就已經編譯到調用對象中了,不一樣於隱式聲明變量在解釋時才被定義爲全局變量,只是在調用outPut(i)時,尚未將它初始化變量,此時的局部變量i是未賦值變量,而不是未定義變量,所以輸出了undefined。上面的代碼等效於下面代碼:
function inner(){
    var i; //定義但不賦值
    outPut(i); //undefined
    i=1;
    outPut(i); //1
}
爲了不上面的這類問題,所以在函數開始位置集中作函數聲明是一個極力推薦的作法。
5、基本類型和引用類型
JS在變量申明時並不須要聲明變量的存儲空間。變量中所存儲的數據能夠分爲兩類:基本類型和引用類型。其中數值、布爾值、null和undefined屬於基本類型,對象、數組和函數屬於引用類型。
基本類型在內存中具備固定的內存大小。例如:數值型在內存中佔有八個字節,布爾值只佔有一個字節。對於引用型數據,他們能夠具備任意長度,所以他們的內存大小是不定的,所以變量中存儲的其實是對此數據的引用,一般是內存地址或者指針,經過它們咱們能夠找到這個數據。
引用類型和基本類型在使用行爲上也有不一樣之處:
//定義一個輸出函數
function outPut(s){
    document.writeln(s)
}
var a = 3;
var b = a;
outPut(b);//3
a = 4;
outPut(a);//4
outPut(b);//3
對基本類型b進行賦值時,其實是又開闢了一塊內存空間,所以改變變量a的值對變量b沒有任何影響。
//定義一個輸出函數
function outPut(s){
    document.writeln(s)
}
var a_array = [1,2,3];
var b_array = a_array;
outPut(b_array); //1,2,3
a_array[3] = 4;
outPut(b_array);//1,2,3,4
上面是對引用類型的變量賦值,實際上他們傳遞的是對內存地址的引用,所以對a_array和b_array的存取,實際上都是操做的同一塊內存區域。若是但願從新分配內存空間存儲引用型變量,那麼我就須要使用克隆方法或者自定義方法來複制引用變量的數據。數組

相關文章
相關標籤/搜索