在 ES6 中新增 letconst 命令,它们都是用于声明一个值。

一、Let

let 命令相当于 var 的迭代版。

let 声明变量的语法和 var 类似,如以下命令就表示用 let 声明变量 b 的值为 2:

var a = 1;
let b = 2;

1.1 块级作用域

需要注意的是,使用 let 声明的变量只能在其所在的块级作用域才能使用。什么意思?请看以下代码对比。

使用 var 方式:

if (true) {
var a = 1;
console.log(a); // 1
}

console.log(a); // 1

而使用 let 方式:

if (true) {
let a = 1;
console.log(a); // 1
}

console.log(a); // 报错: a is not defined

通过以上两段代码,可以知道变量 a 是在 if 代码块中,使用 let 声明的,所以第二段代码中后面那个 console.log(a) 就报错了。

另外,如果尝试着在 let 语句前读取变量,也会报上面的错误。因此 let 不会像 var 一样存在变量前置(提升)。

类似的,while、switch、for 等代码块中声明的变量,在它们外部都不能正常读取到。

我们再来看一个经典的例子,有一组 li 列表,用户点击其中的 li 列表项,获取对应的索引值。

<ul>
<li>aa</li>
<li>bb</li>
<li>cc</li>
</ul>

如果使用 var 来写:

var li = document.querySelectorAll('li');

for (var i = 0; i < li.length - 1; i++) {
li[i].onclick = function() {
console.log(i);
};
}

你会发现,无论点击那个 li 列表项,都是显示 3,即 i 循环后的值。这就是因为没有 块级作用域 的关系。

如果使用 let 声明,则轻松的解决上述问题:

for (let i = 0; i < li.length; i++) {
li[i].onclick = function() {
console.log(i);
};
}

1.2 不能重复声明

使用 var 可以覆盖前面的变量:

var a = 1;
var a = 2;

console.log(a); // 2

let,则不允许重复声明:

var a = 1;
let a = 2;

console.log(a); // 报错:Identifier 'a' has already been declared

当然了,如果多次使用 let 命令去声明同一变量,也是会报错的。

同时,也不能像下面这样重新定义函数的形参。但在函数中新的代码块里定义形参,也没有问题:

// 报错:Identifier 'num' has already been declared
function add(num) {
let num = 1;
}

// 正常运行
function add(num) {
if (true) {
let num = 1;
}
}

二、Const

const 只能用于声明一个只读常量。也就是说,通过 const 声明的值,后期不能修改。

const DOMAIN = 'http://www.xx.com';

DOMAIN = 'http://www.aa.com'; // 报错:Assignment to constant variable

另外,在使用 const 时,不仅要声明常量,同时也要给该常量赋值。不能像 var 那样可以只声明,后期再赋值。比如,以下代码会报错,会提示需要初始化声明的常量:

const DOMAIN; // 报错:Missing initializer in const declaration

而对于前面讲到的 块级作用域 和 不能重复声明 ,const 同样适用。

并且,对于常量而言,最好是使用 大写 字母来定义变量名,这也是业界统一的做法。

三、关于 let 和 const 的使用

如果项目是使用 ES6+ 开发,那么我们大可以抛弃 var 这种定义方式,在代码中全部使用 let 和 const,毕竟它们有诸多好处,也符合未来开发规范,推动 ES6+ 发展。

但看网上很多人纠结是使用 let,还是 const?其中,有人这样说到:

  • 据说,JavaScript内部引擎对 const 做了特别的优化,所以,多用 const,会提升代码执行效率
  • 所有的函数都应该定义为常量

所以,非常建议在代码中全部使用 const。从上面的说法来看,虽然第一点我无从得知,但第二点,我还是比较认同的,毕竟,你不会去重新定义一个函数。但是,如果存在变量的话,你该用 let 还是 得用!