找回密码
 立即注册
首页 业界区 业界 Web前端入门第 56 问:JavaScript 变量声明 var、let、c ...

Web前端入门第 56 问:JavaScript 变量声明 var、let、const 区别

事值 2025-6-3 00:03:33
曾经 var 如帝王一般统治过 JS 的变量声明,直到后来大佬们实在是忍不了 var 那稀烂的声明规则,便引入了 let 和 const 这两大刀斧手,var 被轻轻松松的斩落马下,如今,再难看见 var 的身影。
变量声明

在 JS 中,所有变量都可以用 var、let 和 const 这三个关键字声明。
  1. // 字符串
  2. var name1 = '前端路引';
  3. let name2 = '前端路引';
  4. const name3 = '前端路引';
  5. // 数字
  6. var age1 = 18;
  7. let age2 = 18;
  8. const age3 = 18;
  9. // 布尔值
  10. var isDev1 = true;
  11. let isDev2 = true;
  12. const isDev3 = true;
  13. // 空值
  14. var null1 = null;
  15. let null2 = null;
  16. const null3 = null;
  17. // 数组
  18. var arr1 = [1, 2, 3];
  19. let arr2 = [1, 2, 3];
  20. const arr3 = [1, 2, 3];
  21. // 对象
  22. var obj1 = {};
  23. let obj2 = {};
  24. const obj3 = {};
  25. // 函数
  26. var fn1 = function () {
  27.   console.log('前端路引');
  28. }
  29. let fn2 = function () {};
  30. const fn3 = function () {};
复制代码
以上的各种声明方法都是有效的,JS 语法也没强制要求必须用某个关键字声明变量。
区别

它们之间有哪些恩恩怨怨,为什么会在新的语法中引入 let 和 const 来取代 var 呢?
作用域

var 申明的变量,拥有函数作用域,在整个函数体内部都能访问。
let 和 const 申明的变量是块级作用域,出了代码块(就是 {} 包裹的代码片段)就不可以再访问了。
  1. function funcScope() {
  2.   if (true) {
  3.     var a = 1; // 函数作用域
  4.     let b = 2; // 块级作用域
  5.     const c = 3; // 块级作用域
  6.   }
  7.   console.log(a); // 1(var 穿透了 if 代码块)
  8.   console.log(b); // ReferenceError: b is not defined
  9.   console.log(c); // ReferenceError: c is not defined
  10. }
复制代码
变量申明提升

var 申明的变量,不论在哪个位置申明,都会提升到作用域顶部。
let 和 const 申明存在 暂时性死区(TDZ),这些名词道道记不住也罢,反正您只要知道在申明之前使用会报错就对了。
  1. console.log(x); // undefined(变量提升)
  2. var x = 10;
  3. console.log(x); // 10
  4. console.log(y); // ReferenceError: y is not defined(暂时性死区)
  5. let y = 20;
复制代码
var 申明的变量,在申明之前使用会获取 undefined,这就是所谓的 变量申明提升。
重复声明

var 允许同一个变量重复声明。
let 和 const 禁止重复声明。
  1. var a = 1;
  2. var a = 2; // 允许
  3. console.log(a) // 2
  4. let b = 1;
  5. let b = 2; // SyntaxError: Identifier 'b' has already been declared
  6. const c = 1;
  7. const c = 2; // SyntaxError: Identifier 'c' has already been declared
复制代码
let 和 const 重复声明同一个变量,会报语法错误。
全局作用域下的行为

如果在全局作用域中使用 var 申明一个变量,那么这变量会变成全局对象(如 window)的一个属性。
let 和 const 则不会绑定到全局对象。
什么是全局作用域?比如新建一个 a.js,使用  引入这个 JS 文件到 html 页面中,那么这个 JS 文件最外层就称之为全局作用域。
新建一个 test.html,引入 a.js:
  1. [/code][b]新建一个 a.js:[/b]
  2. [code]// 全局作用域
  3. var globalVar = 1;
  4. console.log(window.globalVar); // 1
  5. let globalLet = 2;
  6. console.log(window.globalLet); // undefined
  7. function test () {
  8.   // 函数作用域
  9. };
  10. {
  11.   // 块级作用域
  12. }
复制代码
可变性

var 和 let 声明的变量可以重新赋值。
const 声明的是常量,必须初始化且不可重新赋值(但对象/数组的内容可修改)。
  1. var str = '前端路引';
  2. str = 'web3dev'; // 允许修改变量
  3. let num = 1;
  4. num = 2; // 允许修改变量
  5. const PI = 3.14;
  6. PI = 3; // TypeError: Assignment to constant variable.(不可重新赋值)
  7. const obj = { a: 1 };
  8. obj.a = 2; // 允许(修改属性)
  9. obj = {}; // TypeError: Assignment to constant variable.(不可重新赋值)
复制代码
为什么 const 申明的数组和对象可以修改?
这就涉及到 引用 这个概念了,可以理解为 数组 和 对象 就像现实中的房子。const 申明就像给房子打上了标签贴,拥有了这个房子的使用权,但这房子不止 const 一个拥有者,房子的主人还能对房子进行室内装修改变。const 的标签贴只能使用一次,要想把这标签再贴在另一座房子,那么就行不通了!!
循环

var 申明的变量会泄露到循环体外部。
let 仅作用于循环体内部。
  1. for (var i = 0; i < 3; i++) {}
  2. console.log(i); // 3
  3. for (let j = 0; j < 3; j++) {}
  4. console.log(j); // ReferenceError: j is not defined
复制代码
let 解决异步回调问题:
  1. // var 的问题
  2. for (var i = 0; i < 3; i++) {
  3.   setTimeout(() => console.log(i)); // 输出 3, 3, 3
  4. }
  5. // let 的解决方案
  6. for (let j = 0; j < 3; j++) {
  7.   setTimeout(() => console.log(j)); // 输出 0, 1, 2
  8. }
复制代码
写在最后

最佳实践推荐:所有变量声明优先考虑使用 const ,如果确定变量需要修改再使用 let。
果您的代码确实需要兼容 2017 年之前的浏览器,那么使用 var 吧,别考虑 const 和 let 了。当然也可以使用 babel 等编译器,将 const 和 let 转换成 var 兼容低版本浏览器。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册