JavaScript 变量声明 let 与 const
数据要存在哪里,才能随时取用?答案是变量。变量就是给数据起一个名字,之后可以通过这个名字存取和引用数据。JavaScript 声明变量有两个关键字,let 和 const,本教程只使用它们,不涉及旧式写法。
变量是什么
可以把变量想象成贴了标签的盒子,盒子里装着数据,标签是变量名。需要用到数据时,叫名字就行,不用记住数据本身。
const name = '小明';
console.log(name);
把字符串 ‘小明’ 存进名为 name 的变量,console.log(name) 输出小明。之后代码里任何地方要用这个名字,直接写 name。
变量声明语句由三部分组成,关键字、变量名、初始值。关键字告诉引擎用哪种方式声明,变量名是数据的名字,等号右边是存入的数据。
用 let 声明可重新赋值的变量
let 声明的变量可以重新赋值,也就是盒子里的东西可以换。
let count = 1;
console.log(count); // 输出 1
count = 2;
console.log(count); // 输出 2
注意重新赋值时不写 let,直接写变量名。同一个变量第二次用 let 声明会报错。
典型用 let 的场景包括计数器、累加和、当前分数等,这些值会随程序运行变化。
用 const 声明常量
const 声明的变量不能重新赋值,声明时必须给初始值,之后不能再改。这类变量叫常量。
const PI = 3.14;
console.log(PI); // 输出 3.14
PI = 3.15;
// 报错,TypeError,常量不能重新赋值
给 const 变量重新赋值,控制台会报 TypeError。声明时省略初始值同样报错,const 没有默认值可选。
何时用 let,何时用 const
原则很简单,默认用 const,只有确定这个变量需要重新赋值时才用 let。这是现代 JavaScript 社区的一致推荐。
理由包括
- const 传达的信息更准确,读者一眼知道这个值不会变,思考负担更小。
- 防止自己或他人不小心改动不该改的值,在编译器层面提前拦截。
- 大部分变量其实声明后就不变了,const 恰好够用。
拿不准时先写 const,后续发现要重新赋值再改成 let,成本很低。
const 声明的对象,属性可以改
这是新手最容易困惑的点。const 限制的是变量和值的绑定关系,变量不能再指向其它值,但对象本身的内容不受影响。对象的内容由属性管理,改属性不违反 const 规则。
const obj = { name: '张三' };
obj.name = '李四';
console.log(obj.name); // 输出 李四
// obj = { name: '王五' }; 报错,整体重新赋值不被允许
obj 变量始终指向同一个对象,这没有变。变的只是对象内部 name 属性的值,这是完全合法的。数组同理,const 声明的数组可以修改元素,比如 push 新元素,同样不违反规则。这个现象在后面对象和数组的章节会反复遇到。
变量命名规则
变量名不是随便取的,有硬性规则
- 只能由字母、数字、下划线 _ 和美元符 $ 组成。
- 不能以数字开头,1name 不合法,name1 合法。
- 不能是保留字,比如 let、const、if、for 这些引擎占用的名字。
- 区分大小写,name 和 Name 是两个不同的变量。
中文也可以作为变量名,但项目里不推荐,混排会显得风格混乱。命名建议有两条,语义化命名,用 userName 而不是 a。变量名统一 camelCase,第一个单词小写,后续单词首字母大写。
声明之前不能访问
let 和 const 声明的变量,在声明语句之前不能访问,强行访问会报错,这个区域叫暂时性死区。
console.log(age);
// 报错,age 在声明之前不能访问
const age = 18;
为什么会有这个限制,涉及块级作用域的概念,在 JavaScript 作用域 一篇会详细展开。现在先记住这个现象,声明永远放在使用之前,这也是代码可读性高的表现。
小结
- 变量是数据的名字,通过名字存取和引用数据。
- let 用于需要重新赋值的变量,重新赋值时不写关键字。
- const 用于不能重新赋值的常量,重新赋值报 TypeError。
- 默认用 const,确定需要重新赋值才用 let。
- const 限制的是变量与值的绑定关系,对象的属性可以正常修改。
- 变量名由字母、数字、下划线、美元符组成,不能数字开头、不能是保留字、区分大小写,命名用语义化 camelCase。
- let 和 const 在声明之前不能访问,声明放在使用之前。