let, const, var, and hoisting

by Aaron • 10/11/2022, 11:26: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.