let, const, var, and hoisting

by Aaron • 10/10/2022, 9:36:17 AM

比較 let, const 和 var 的差異。

  1. function scope vs block scope
//function scope
function foo() {
  //...This is function scope
}

// block scope
// block scope如果在代碼塊 {...} 內聲明了一個變量,那麼這個變量只在該代碼塊內可見。
if (condition) {
  //...This is block scope
}

let 和 const 只在 block 使用,而 var 在 function 外會被視為 global variable 需注意!

if (condition) {
  let localVar = "I am local variable";
}
console.log(localVar);
// localVar is not defined

if (condition) {
  var globalVar = "I am global variable";
}
console.log(globalVar);
// output: I am global variable
  1. 重複宣告

let 和 const 不能重複宣告, 而 var 可以。

let foo1 = 1;
let foo1 = 1;
// Identifier 'foo1' has already been declared

var foo2 = 1;
var foo2 = 1;
  1. hoisting

foo 應該要造成 error foo is not defined,但卻可以輸出為 undefined

console.log(foo); // undefined
var foo = 5;

上面的例子可以想成

var foo;
console.log(foo);
foo = 5;

在 function 內

function foo1() {
  console.log(v); // output: undefined
  var v = 2;
  console.log(); // output: 2
}
foo1();

function foo2(v) {
  console.log(v); // output: 1
  var v = 2;
  console.log(); // output: 2
}
foo2(1);

let, const 會被 hoisted 到 uninitialized 的狀態

var v1 = 10;
function foo1() {
  console.log(v1); // Cannot access 'v1' before initialization
  let v1;
}
foo1();

var v2 = 10;
function foo2(v2) {
  console.log(v2);
  let v2; // Identifier 'v2' has already been declared
}
foo2();

如果完全忘記了聲明(並且只初始化了值),則變量不會被提升

console.log(num); // Throws ReferenceError exception - the interpreter doesn't know about `num`.
num = 6; // Initialization
  1. 為何需要 hoisting?
foo("hello");

function foo(text) {
  console.log(`In foo: ${text}`);
}
// output: In foo: hello
(function foo1() {
  for (let i = 0; i < 10; i++) {
    if (i % 2 === 0) {
      foo2(i);
    }
  }
})();

function foo2(num) {
  console.log(`In foo2: ${num}`);
}

/* output: 
In foo2: 0
In foo2: 2
In foo2: 4
In foo2: 6
In foo2: 8
*/
© 2025 Aaron Li. All Rights Reserved.