1. var、let、const概述
ES6发布前,Javascript只能通过var声明变量的方式,常量、块级变量、函数变量这些概念的差别都不能很好的体现出来,于此同时,加入你要使用或者提供一个api,var声明的变量可随时被修改和重新分配的问题,会让你时刻担心代码是否能正常运行。
ES6为我们带来了let、const,我们先来了解一下三个标识符的特征:
var: var定义一个变量,这个变量可以被重新分配、可能会被用于整个函数(Function Scope)
let: let定义一个变量,这个变量可以被重新分配,但let可以被用于块级作用域(Block Scope),不存在变量提升
const: const定义一个常量,不可以被重新分配
下面,我们将从作用域、变量提升、变量重新分配几个方面讲解var、let、const的差别以及用法实践。
2. 作用域
var的作用域
当var定义的变量在函数内部时,通过函数外部调用变量,会导致 Uncaught ReferenceError: i is not defined 错误:
function doSomeThing () {
var i = 1;
}
console.log(i); // Uncaught ReferenceError: i is not defined
但是,在if、for、while这样的块级语句内通过var声明变量,仍然可以在块语句外部访问:
if (true) {
var i = 1;
}
console.log(i); // 1
let的作用域
let定义了一个拥有块级作用域属性的变量,同样的代码我们用let声明变量可以看看结果:
if (true) {
let j = 1;
}
console.log(j); // Uncaught ReferenceError: j is not defined
const的作用域
const的作用域规则和let类似,同样的代码我们用const声明变量可以看看结果:
if (true) {
const k = 1;
}
console.log(k); // Uncaught ReferenceError: k is not defined
3. 变量提升
先说结论:var声明的变量存在变量提升,let和const则不会
来一个例子体会一下:
console.log(m); // undefined
var m = 1;
console.log(n); // Uncaught ReferenceError: n is not defined
let n = 1;
console.log(v);
const v = 1; // Uncaught ReferenceError: v is not defined
推荐使用let和const理由之一,就是可以避免在使用后面声明的变量时出现未知错误。
4. let、const用法示例
明白var、let、const的区别,有助于我们用更简洁易懂的方式表达我们的代码。
先看看什么情况下你才用var?
通过上面的介绍,我们大概了解到var区别于let、const的地方在是:函数作用域、可被修改、变量提升,所以在函数声明优先于变量声明,但是函数调用在变量声明之后的逻辑里可以用到var。
var f = {
doThings: function () {
console.log(i);
}
}
var i = 1; // 声明变量
// 函数调用
f.doThings(); // 1
使用let的场景?
let一般用于for(while)循环和数学表达式计算中
for (let i = 0, len = 100; i < len; i++) {
console.log(i);
}
那么有个问题,上面的for循环用var声明i变量也是可以的啊?
再来看一段代码:
for (var i = 0; i < 100; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
// 控制台会一直输出100
// 改成 let
for (let i = 0; i < 100; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
解释一下为什么会这样:let的作用局的块级作用局,即每次循环的i的作用域就是本次循环,下一次循环重新定义变量i。
const的使用场景?
const声明了一个常量,推荐将const常量用于别名,降低常量的记忆难度。
const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
结束
建议在”use strict”模式下,使用let和const替代var,以保证代码的整洁和可读。