今天在 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 則留言 :
Brilliantly articulated! Your post is a standout, offering insightful perspectives. Appreciate you sharing your valuable perspective.
張貼留言