2023年11月13日 星期一

Javascript ES6 學習筆記 : var 的變數提升 (variable hoisting)

今天在 Hahow 企業版的 ES6 課程中學到用 var 宣告之變數有 variable hoisting 的怪異行為, 如下列範例所示 :

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title></title>
</head>
<body>
  <script>
    document.write(a + "<br>");   
    var a=123;   
    document.write(a + "<br>");    
  </script>
</body>
</html>


此程式先輸出一個未定義的變數 a, 所以輸出 undefined, 第二列用 var 宣告變數 a 並賦值為 123, 第三列再次輸出 a 變數就會輸出 123 了. 

如果是 Python 的話, 用 print() 輸出一個未定義變數會出現錯誤 (比較合理), 但 Javascript 會兩次掃描程式, 第一次掃描時發現後面有宣告 a, 所以第二次掃描執行時就輸出 undefined, 這種怪異行為稱為變數提升. 

ES6 提出的 let 變數宣告指令就是為了矯正這種情況, 在第一次掃描雖然發現後面有定義 a 變數, 但第二次掃描時並不會進行變數提升, 所以會出現執行錯誤 (無法存取變數 a) : 

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title></title>
</head>
<body>
  <script>
    document.write(a + "<br>");     //錯誤 : 無法存取 a 變數
    let a=123;      //let 不會做變數提升
    document.write(a + "<br>");   
  </script>
</body>
</html>


此網頁無法顯示, 因為執行 document.write(a + "<br>") 時出現無法存取 a 變數的錯誤, 在 Chome 按 F12 切換到主控台顯示如下錯誤訊息 :




為了避免汙染全域物件, 應盡量使用 let, 不要使用 var. 

1 則留言 :

Ratings 提到...

Brilliantly articulated! Your post is a standout, offering insightful perspectives. Appreciate you sharing your valuable perspective.