学JavaScript时,很多人会忽略“变量声明”这个基础操作,觉得“不就是var a = 1
吗?”。但等你写了几百行代码,突然被ReferenceError: a is not defined
报错,或者发现循环里的变量“串味”了,才会意识到:变量声明的方式,直接决定了代码的行为和稳定性。
这篇文章不玩比喻,只讲技术细节。我们从最基础的var
开始,逐个拆解let
、const
的特性和使用场景,帮你彻底理清“变量声明”的底层逻辑。
一、变量声明的本质:给数据“贴标签”
变量声明的核心是“为数据分配一个可访问的名称”。比如const PI = 3.14
,本质是告诉JavaScript引擎:“我需要一个叫PI
的容器,里面存3.14这个数值,后续用PI
就能找到它。”
但JavaScript提供了三种声明方式——var
、let
、const
,它们的区别藏在“作用域”“可变性”“声明规则”三个底层规则里。
二、var
:经典的“全局战士”
var
是JavaScript最早期的变量声明方式(ES5及之前),它的特性可以用一句话总结:声明的变量是“全局的”,且存在“变量提升”。
1. 全局作用域:跨函数“存活”
var
声明的变量可以在函数内外“自由流动”。举个例子:
function setAge() {
var age = 25; // 在函数内部用var声明
}
setAge();
console.log(age); // 输出25(而不是报错)
即使age
是在函数内部声明的,函数外部也能访问到它。这在小项目中可能方便,但在大型代码里,变量会像“野孩子”一样到处乱窜,导致命名冲突、调试困难。
2. 变量提升:代码执行前的“预加载”
var
声明的变量会在代码执行前被“创建”(只是值未定义)。比如:
console.log(age); // 输出undefined(不会报错)
var age = 25;
这行代码的实际执行顺序是:
var age; // 变量提升:先声明变量(值默认undefined)
console.log(age); // 此时age的值是undefined
age = 25; // 后续赋值
这种“先声明后执行”的特性,容易导致“明明声明了,为啥输出undefined”的困惑。
总结:var
的适用场景
除非你在维护一个非常古老的项目(比如10年前的代码),否则不建议新手使用var
。它的全局作用域和变量提升特性,会让代码变得难以维护。
三、let
:灵活的“块级管家”
let
是ES6(2015年)引入的新特性,它的出现主要是为了解决var
的两个核心问题:全局污染和变量提升。
1. 块级作用域:只在“大括号”内生效
let
声明的变量仅在“代码块”(由{}
包裹的区域)内有效。比如:
if (true) {
let score = 90; // 在if块内用let声明
console.log(score); // 输出90(正常)
}
console.log(score); // 报错:score is not defined(块外无法访问)
score
就像被关在一个“小房间”里,出了房间就找不到了。这种“块级作用域”特性,能避免变量在不同代码块间“串味”,是现代JavaScript的必备技能。
2. 可修改,但禁止重复声明
let
允许修改变量的值(比如循环计数器),但禁止对同一个变量重复声明。比如:
let age = 25;
age = 26; // 允许:修改值
let age = 27; // 报错:Identifier 'age' has already been declared(不能重复声明)
这能帮你避免“手滑重复声明”的低级错误,让代码更健壮。
总结:let
的适用场景
所有需要“修改值”的场景。比如循环里的计数器(let i = 0; i < 10; i++
)、用户输入的实时更新(let inputValue = ''
),用let
都能完美胜任。
四、const
:严格的“常量卫士”
const
也是ES6引入的特性,它的设计目标很明确:声明一个“不可修改”的常量。
1. 必须初始化,且不可重新赋值
const
声明变量时必须立刻赋值,且后续不能修改它的值。比如:
const PI = 3.14; // 正确:声明时赋值
PI = 3.1415; // 报错:Assignment to constant variable(不能修改)
const name; // 报错:Missing initializer in const declaration(必须初始化)
这像给变量上了一把“锁”,确保它的值不会被意外修改——尤其适合存储数学常数(PI
)、配置项(API_URL
)等固定值。
2. 对象/数组可修改内容,但不可修改引用
const
限制的是“变量的引用”,而不是“变量的内容”。比如:
const user = { name: '小明' };
user.name = '小红'; // 允许:修改对象的属性(内容变化)
user = { name: '小红' }; // 报错:Assignment to constant variable(不能修改变量引用)
这就像你买了一个固定的快递柜(const
),但快递柜里的包裹可以换——只要不换快递柜本身就行。
总结:const
的适用场景
所有“不需要修改”的变量。无论是数字、字符串,还是对象、数组,只要你确定它的值不会变,就应该用const
。它是现代JavaScript的“最佳实践默认选择”。
五、怎么选?记住这三条黄金规则
现在你可能想问:“那我该怎么选var
、let
、const
?” 答案很简单,记住这三条:
- 优先用
const
:只要变量不需要修改,就用const
。它能帮你避免“手滑改值”的错误,还能让代码更易读(别人一看就知道这变量是固定的)。 - 其次用
let
:如果变量需要修改(比如循环计数器、用户输入),就用let
。它的“块级作用域”能帮你避免变量污染。 - 尽量不用
var
:除非你在维护老项目,否则var
的全局作用域和变量提升特性,足够让你的代码变得难以维护。
写在最后
变量声明是JavaScript最基础的操作,但它藏着编程的核心逻辑——如何通过规则约束数据,让代码更可控、更健壮。搞懂var
、let
、const
的区别,不仅能让你少写bug,还能让你更理解代码的“运行规则”。
下次写代码时,不妨多花两秒想想:“这个变量需要改吗?它应该只在当前块里生效吗?” 这些小习惯,会让你离“写出优雅代码”的目标更近一步。
金句:变量声明不是“随便写写”的小事,它是你和计算机“对话”的第一行代码——清晰、准确的声明,是对自己和代码最基本的尊重。
评论