目录
在 JavaScript 中,声明变量的方式主要有三种:var
、let
和 const
。它们看似只是语法不同,但在作用域、提升(Hoisting)、可变性等方面有明显区别。本文将详细讲解它们的特性和使用场景。
1. 基本概念
1.1 var
出现时间:ES5 及之前版本唯一的变量声明方式
作用域:函数作用域(function scope)或全局作用域
变量提升:会被提升到当前作用域顶部,未赋值前默认为
undefined
可重复声明:同一作用域内可以重复声明同名变量
适用场景:现在已不推荐使用,除非是为了兼容旧代码
console.log(a); // undefined(已提升) var a = 10; function testVar() { var b = 20; if (true) { var b = 30; // 同一函数作用域 } console.log(b); // 30 } testVar();
1.2
let
出现时间:ES6 引入
作用域:块级作用域(block scope)
变量提升:会提升,但处于暂时性死区(TDZ),在声明前访问会报错
可重复声明:同一作用域内不能重复声明同名变量
适用场景:声明会变化的变量(推荐使用)
// 暂时性死区示例 { // console.log(c); // ReferenceError let c = 10; console.log(c); // 10 } // 块级作用域 function testLet() { let x = 1; if (true) { let x = 2; // 与外层 x 不同 console.log(x); // 2 } console.log(x); // 1 } testLet();
1.3
const
出现时间:ES6 引入
作用域:块级作用域
变量提升:同样存在,但受暂时性死区影响
可重复声明:不能重复声明同名变量
必须初始化:声明时必须赋值
不可更改绑定:变量绑定的引用不可更改,但如果是对象或数组,内容是可变的
const PI = 3.14159; // PI = 3; // TypeError: Assignment to constant variable. const arr = [1, 2, 3]; arr.push(4); // 允许 console.log(arr); // [1, 2, 3, 4] const obj = {name: 'Tom'}; obj.age = 18; // 允许 console.log(obj); // {name: 'Tom', age: 18}
2. 三者区别对比表
特性 | var | let | const |
---|---|---|---|
作用域 | 函数作用域/全局作用域 | 块级作用域 | 块级作用域 |
变量提升 | 有,初始化为 undefined |
有(TDZ 限制) | 有(TDZ 限制) |
重复声明 | 允许 | 不允许 | 不允许 |
必须初始化 | 否 | 否 | 是 |
可重新赋值 | 是 | 是 | 否(引用不可变) |
常用场景 | 旧代码兼容 | 会变化的值 | 常量或引用不变的值 |
3. 使用建议
优先使用
const
如果变量不会被重新赋值,用const
可以避免意外修改。需要修改的变量用
let
当变量需要多次赋值时使用let
,保证块级作用域安全。尽量避免
var
除非维护旧项目或必须兼容低版本浏览器,否则不推荐使用var
。
4. 总结
var
→ 旧时代的选择,函数作用域,变量提升,容易出 buglet
→ 现代可变变量,块级作用域,安全性高const
→ 现代常量,块级作用域,引用不可变(对象内容可变)
在实际开发中,一般遵循这样的原则:
先用
const
,如果需要修改值再改为let
,避免使用var
。