点此查看 所有教程、项目、源码导航
文章目录
- [1. 背景介绍](#1. 背景介绍)
- [2. var 的常见问题](#2. var 的常见问题)
-
- [2.1 没有块级作用域](#2.1 没有块级作用域)
- [2.2 允许重复声明](#2.2 允许重复声明)
- [2.3 变量提升](#2.3 变量提升)
- [3. let](#3. let)
-
- [3.1 块级作用域](#3.1 块级作用域)
- [3.2 不允许重复声明](#3.2 不允许重复声明)
- [3.3 暂时性死区](#3.3 暂时性死区)
- [4. const](#4. const)
-
- [4.1 基本特性](#4.1 基本特性)
- [4.2 引用类型的特殊点](#4.2 引用类型的特殊点)
- [5. 使用建议](#5. 使用建议)
- [6. 小结](#6. 小结)
1. 背景介绍
在 ES6 之前,声明变量只能使用 var。小规模代码里,它带来的问题或许不容易察觉,但一旦项目体量变大、多人协作,var 的作用域缺陷就会被放大,很容易出现变量意外泄露、值被莫名覆盖、提升导致的诡异 bug,排查起来十分耗费精力。
let 和 const 就是 ES6 推出用来替代 var 的变量声明方式,也是往后写 Vue 代码最常用的声明关键字。熟练掌握两者,是理解块级作用域、避开 JS 变量坑的第一步。
2. var 的常见问题
先简单回顾 var 的几个典型缺陷。
2.1 没有块级作用域
使用 var,在 if、for 代码块里面声明的变量,在块外面依然可以访问。
js
if (true) {
var name = "zhangsan";
}
console.log(name);
正常期望是出块之后变量失效,但上面代码可以打印出结果,容易污染外部变量。
2.2 允许重复声明
同一个作用域内,可以反复使用 var 声明同名变量,不会报错,会悄悄覆盖原有值。
js
var num = 10;
var num = 20;
代码不会提示异常,一不小心就覆盖数据。
2.3 变量提升
var 存在变量提升,在声明语句之前访问变量,得到 undefined,而不是直接报错,这种隐性行为很容易制造难以定位的 bug。
js
console.log(a);
var a = 100;
3. let
let 用来声明可变变量,后续可以重新赋值。
3.1 块级作用域
let 拥有块级作用域,被一对大括号 {} 包裹起来就是一个独立块,块内声明的变量外部无法访问。
js
if (true) {
let msg = "hello";
}
// console.log(msg); // 报错,msg 在外部不可访问
循环里面使用 let 也会符合预期,是开发中最常用的场景。
3.2 不允许重复声明
同一个作用域,不能重复声明同名变量。
js
let x = 1;
// let x = 2; // 报错
3.3 暂时性死区
let 也存在提升,但是引入了暂时性死区:在代码执行到声明语句之前,不能访问该变量,访问直接抛出错误。
js
// console.log(b); // 报错
let b = 20;
这个特性避免了在变量声明前误读,比 var 更加安全。
4. const
const 用来声明常量,一旦绑定,就不允许重新赋值。
4.1 基本特性
const 同样具备块级作用域、不能重复声明、存在暂时性死区。
js
const PI = 3.1415;
// PI = 3; // 报错,不能重新赋值
4.2 引用类型的特殊点
这里是高频考点:const 限制的是变量引用地址,不是对象或者数组里面的数据。
js
const arr = [1, 2, 3];
arr.push(4);
console.log(arr);
// arr = []; // 报错,不能直接替换数组引用
如果是对象,可以修改对象内部属性;但是不能让变量指向另外一个全新对象。
5. 使用建议
日常开发推荐优先按照这个习惯:
- 如果变量后续需要重新赋值,使用
let; - 如果确定不会重新赋值,优先使用
const; - 尽量不要再使用
var。
这个习惯放到 Vue 里面同样适用:普通可变响应式变量交给
ref,而普通临时变量,遵循const > let的顺序选择。
6. 小结
let 和 const 引入块级作用域,修复了 var 在大型项目中容易爆发的各类隐患。需要记住,const 并不是代表里面的数据绝对不可修改,只是不能更换引用,这点很容易踩坑。
这两个关键字是后续所有 ES6 语法的基础,同时在 Vue 组件、组合式代码中随处可见,是必须熟练掌握的内容。