DEV Community

SGsSY
SGsSY

Posted on

The Most Familiar Stranger - JavaScript - 變數

分享記錄檔 YouTube

在 JavaScript 內要宣告一個變數我們可以使用 varletconst

那他們之間有什麼差異呢? 為什麼我們在實務應用上總是使用 let、const 呢?

作用域 ( Scope )

constlet 是區塊作用域 ( block scope ),var 是函式作用域 ( function scope )

function test() {
    {
        const x = 10;
    }
    console.log(x); // Uncaught ReferenceError: x is not defined
    {
        let y = 20;
    }
    console.log(y); // Uncaught ReferenceError: y is not defined
    {
        var z = 30;
    }
    console.log(z); // 30
}
console.log(z); // Uncaught ReferenceError: z is not defined
Enter fullscreen mode Exit fullscreen mode

提升 ( Hoisting )

是一種將變數、函式宣告提升到作用域頂部的行為。不同的是,如果我們沒有宣告就直接使用該變數,var 會回傳 undefined,letconst 會報錯。

function test() {
  console.log(a); // undefined
    var a = 10;
}
test();

// 實際上 JS Runtime 會像這樣
// function test() {
//   var a;
//   console.log(a);
//   a = 10;
// }
// test();
Enter fullscreen mode Exit fullscreen mode
function test() {
  console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
  let a = 10;
}
test();
Enter fullscreen mode Exit fullscreen mode
function test() {
  console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
  const a = 1;
}
test();
Enter fullscreen mode Exit fullscreen mode

💡 變數從區塊的一開始到他被初始化之前就是 temporal dead zone

var 有什麼問題?

實務上我們都不去使用 var,因為 var 的函式作用域、可重複宣告的特性很容易造成開發上的混亂

function test() {
    var name = 'John';
    // 200 行複雜程式判斷
    if (true) {
        var name = 'James'; // 重複宣告不會報錯,會意外覆蓋掉原有變數的值
    }
    console.log(`I am ${name}`); 
}
test(); // I am James
Enter fullscreen mode Exit fullscreen mode

letconst 則不能重複宣告

let name = 'John';
let name = 'James'; // Uncaught SyntaxError: Identifier 'name' has already been declared
Enter fullscreen mode Exit fullscreen mode

何時該使用 const ? 何時該使用 let ?

如果該變數不變則使用 const,會變則使用 let。

💡 變不變指的是記憶體位置的改變。

const b = {};
console.log(b) // {}

b.name = 'John';
console.log(b) // {name: 'John'}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)