置頂 0%

初探var及let變數

前言

JavaScript中不同宣告變數的關鍵字會有不同的調用區域(也稱作用域)(Scope),我自己剛接觸JavaScript時,曾經沒有使用var 關鍵字來宣告變數,所以導致宣告的變數無論在哪裡都會是全域變數,這會很容易造成後面誤用或干擾到區域變數,進而成為系統程式bug的原因。因此,對於變數的作用域範圍必須要有所掌握,才可以寫出具有穩定性的程式!

關鍵字var let const 的比較

var let const
變數宣告方式 變數宣告方式 (來宣告在可能會有再次賦值的變數) 常數宣告方式 (如同JAVA的關鍵字final),像是const PI = 3.14,且const宣告變數時就會有初始化的動作,若之後再次賦值,就發生Uncaught TypeError: Assignment to constant variable的錯誤喔!
函式範圍來決定變數的作用域 (function scope),且要注意會有變數提升(Variables Hoisting)的特性 有效作用域是根據以區塊(block)來決定,稱為block scope,區塊就是大括號{}或小括號()裡面的範圍 ,不會有 hoisting 的狀況 如同let的作用域一樣,也是透過區塊(block)來決定來決定作用域範圍,不會有 hoisting 的狀況
可以重複宣告 不可重複宣告 不可重複宣告
宣告前存取或覆值就會回傳undefined 宣告前存取或覆值會直接出現ReferenceError,並終止程式執行 宣告前存取或覆值會直接出現ReferenceError,並終止程式執行
ES6後比較少用 常用來宣告for迴圈中的循環變數 可以使用在陣列、物件或函式等參照類型的使用
  • ES6之後都漸漸使用let來宣告變數,主要是希望開發的專案能具有穩定性及可讀性

    • let來宣告變數不會汙染到全域物件,而且可以避免區域變數覆蓋全域變數循環變數洩漏為全域變數,下面的程式碼為用var來宣告變數可能會遇到的狀況
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //區域變數覆蓋全域變數
    var tmp = 'test';//Global Variable
    function f(){
    glo_tmp = 'global';//Global Variable
    //var glo_tmp = 'global123'; //如果沒有這行var宣告變數,glo_tmp就是全域變數,可以透過window.glo_tmp取得
    console.log(tmp); //undefined,下面宣告的var tmp = 'new';,var tmp;會自動提升到函式最上面做初始化的動作;
    if(true){
    var tmp = 'new';
    }
    console.log(tmp);//new
    };
    f();
    console.log(tmp);//test
    //循環變數洩漏為全域變數
    console.log(window.glo_tmp);
    var s = 'test';
    for(var i=0; i<s.length; i++){
    console.log(s[i]);
    }
    console.log(i);// 4
    • 如果var宣告變數不是在函數當中的話,就會成為全域物件的變數&nbsp;;&nbsp;let宣告的變數有效範圍則是在if的大括號裡面而已
      1
      2
      3
      4
      5
      6
      if(true) {
      var v = 'v';
      let a = 'a';
      }
      console.log(v); //v
      console.log(a); //Uncaught ReferenceError: a is not defined
  • 在沒有var宣告情況下都視為全域變數,像是下面的glo_tmp,同時也是wondow物件的一個屬性,所以可以透過window.glo_tmp取得值

    • 可以使用 delete glo_tmp來刪除物件屬性,並會return一個true
    • 盡可能避免此種宣告方式,很容易造成系統上面的bug
1
2
3
4
5
6
function f(){
glo_tmp = 'hello'; //Global Variable
console.log(glo_tmp); // 印出hello
};
f();
console.log(glo_tmp);// 印出hello
  • 只要存取的變數在函式當中有宣告,就算變數的存取比宣告早,也不會變成是全域變數的存取,但只要函式裡面都沒有做var宣告變數,最後印出來的tmp就會是hello
1
2
3
4
5
6
7
8
9
10
11
var tmp = 'test';//Global Variable
function f(){
tmp = 'hello'; //這裡的變數tmp是區域變數的tmp
console.log(tmp); //hello
if(true){
var tmp = 'new';
}
console.log(tmp);//new
};
f();
console.log(tmp);//test