網頁

2017/8/24

JavaScript let和var的差別

ECMAScript 6多了let關鍵字,和var一樣用來宣告變數,差別在於作用域(scope)的範圍。

let變數的作用域為block;var變數的作用域為function。

見下面範例,可以看到letvar行為上的差異。
if區塊中變數var_a和一開始宣告的var_a是指向同個位置,if區塊中的var_a並沒有因為位在if區塊中而獨立於區塊外的var_a

let_b變數就不同了,區塊內的let_b和一開始宣告的let_b是獨立的兩個變數,一旦if區塊結束後,區塊中的let_b就會消滅。

至於在function中的var_a和function外的var_a就是不同的變數了,function中的var_a僅作用在function區塊中而已,而function中的let_b就和在if區塊中的行為一樣,是個獨立於區塊外的變數。

var var_a = 1;
let let_b = 50;

if(var_a < let_b){
  console.log("var_a:" + var_a); // var_a:1
  // console.log("let_b:" + let_b); // let_b is not defined
  var var_a = 2;
  let let_b = 60;
  console.log("var_a:" + var_a); // var_a:2
  console.log("let_b:" + let_b); // let_b:60
}
console.log("var_a:" + var_a); // var_a:2
console.log("let_b:" + let_b); // let_b:50

test();

function test(){
  console.log("var_a:" + var_a); // var_a:undefined
  // console.log("let_b:" + let_b); // let_b is not defined
  var var_a = 3;
  let let_b = 70;
  console.log("var_a:" + var_a); // var_a:3
  console.log("let_b:" + let_b); // var_a:70
  
}

console.log("var_a:" + var_a); // var_a:2
console.log("let_b:" + let_b); // let_b:50

可以注意到範例中,if或function區塊內一開始印出console.log(let_b)都被我特別註解起來,這是letvar的另一個差異。let變數在宣告之前不可被存取,否則會出現錯誤,又稱為Temporal Dead Zone(TDZ),而var變數不會出現錯誤,只是會印出"undefined"。

不過若區塊中沒有宣告同樣名稱的let變數,則會存取外部的變數,例如

var var_a = 1;
let let_b = 50;

if(var_a < let_b){
  console.log("var_a:" + var_a); // var_a:1
  console.log("let_b:" + let_b); // let_b:50
}
console.log("let_b:" + let_b); // let_b:50


此外宣告為全域變數的letvar變數的差別在於,全域的var變數會被加入全域的Window物件中,而let變數不會,例如

var var_a = 1;
let let_b = 50;

console.log(window.var_a); // 1
console.log(window.let_b); // undefined

而在同一block中的var變數可以重複宣告,但let變數不行重複宣告。

var var_a = 1;
let let_b = 50;

var var_a = 2;
let let_b = 60; // Uncaught SyntaxError: Identifier 'let_b' has already been declared

參考

沒有留言:

張貼留言