在 JavaScript 中用 var, let, 以及 const 有什么差别?什么时候该用哪个?

2023年2月9日

💎 加入 E+ 成長計畫 與超過 500+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

在 JavaScript 中用 var, let, 以及 const 有什么差别?」是在前端、JavaScript 面试中常见的考题。在面试时可以先大方向地列点说出异同之处,然后再针对每一个点进行深入说明。以下是以第一人称撰写的参考拟答。

var, let, 以及 const 都是在 JavaScript 用来做变数宣告的保留字,在 JavaScript 早期只有 var,直到 ES2015 (ES6) 时才加入了 letconst

他们之间主要有 4 个不同

  1. 在作用域上,var 可以是全域、也可以是以函式作为范围;letconst 则是以区块作为范围。
  2. 在宣告上,var 可以被重复宣告,但是 letconst 则不行。
  3. 在提升上,var 宣告的变数会自动初始化值为undefined,因此在宣告前就使用变数,不会出现错误,而会是undefined ;但是letconst 宣告的变数则不会自动初始化,而是会进到暂时死区(TDZ),因此在letconst 宣告变数前使用该变数,会出现错误。
  4. letconst 在绝多数面向都是一样,两者的一大区别在于,用 let 宣告的变数可以重新赋值,但是用 const 的不行。

作用域的差别

在作用域上,var 可以是全域、也可以是以函式作为范围,letconst 则是以区块作为范围。 ;当我们在一个文件的最外层使用 var 来宣告变数,这时它的范围会是全域,因此当我们在 console 当中输入

var greeting = "hello";

我们可以接着输入

window.greeting; // "hello"

其结果会是 hello,但是用 letconst 宣告则不会有同样效果。而除了全域,var 在某个函式中范围则是该函式。

var 可以重复宣告

在宣告上,var 可以被重复宣告,但是 letconst 则不行。所以当使用 var 时,可以做到以下这样:

var greeting = "Hello! This ExplainThis :)";
var greeting = "ExplainThis is a website that helps you learn programming!";

let 可以重新赋值,但不能重复宣告,所以会如下面这样:

// 不行这样!不然会有 SyntaxError: Identifier 'greeting' has already been declared
let greeting = "Hello! This ExplainThis :)";
let greeting = "ExplainThis is a website that helps you learn programming!";

// 可以这样 :)
let greeting = "Hello! This ExplainThis :)";
greeting = "ExplainThis is a website that helps you learn programming!";

提升上的差别

在提升上,var 宣告的变数会自动初始化,因此在宣告前就使用变数,不会出现错误,而会是 undefined ,例如下面这样

console.log(greeting); // undefined
var greeting = "hi there";

但是 letconst 则不会,而是会进到暂时死区 (TDZ),因此在 letconst 宣告变数前使用该变数,会出现错误:

console.log(greeting); // Uncaught ReferenceError: greeting is not defined
let greeting = "hi there";

let 可以重新赋值 const 不行

letconst 在绝多数面向都是一样,两者的一大区别在于,用 let 宣告的变数可以重新赋值,但是用 const 的不行。

特别注意,这边指的差别是在于「赋值」,而不是改变某个变数。如果是改变某个变数,若该变数是原生值(primitive values),例如字串、数字,letconst 都不能改变;但假如该变数是**物件(objects) **,则不论letconst 在宣告后,都仍是可以改变该物件。

所以下面这个例子是可行的

const user = { name: "小明" };
user.name = "小王";
console.log(user); // {name: '小王'}

延伸问题:什么时候该用 let ? 什么时候用 const ?

关于这问题,没有一个标准答案。业界目前普遍的观点是多数时候都用const,只有非得要重新赋值才用let,甚至有一条 ESLint 的规则prefer-const 是在规范这个写法。

不过也有另一个观点,例如 React 核心团队的 Dan Abramov 就表示自己是看心情决定用哪一个,换句话说并没有一个固定规则。当然他也提到如果团队已经有某个使用的原则,那他会尊重团队订定出的使用原则,以代码的一致性为主。

这边附上 Dan Abramov 分享这题的片段

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們