由来
let是ES6中新增的命令,用于声明变量,因此在ES6中尝试用let来替代var。
区别
1. 作用范围
let
只作用于命令所在的代码块。
{
let one = 1;
var two = 2;
}
console.log(one); // ReferenceError: one is not defined
console.log(two); // 2
上述代码在代码块中声明两个变量one
,two
, 然后在代码块外部进行调用,结果只有var
声明的变量返回正确的值,由此佐证let
命令只作用于命令所在代码块。
2. 结合for循环
let
命令只作用于命令所在的代码块,那么for
循环体内部的每次循环的let
所声明的变量都是局部变量,而var
所声明的则是全局变量,因此每次for
循环都会修改该变量的值。具体代码如下:
for(var i = 0; i < 5; i++){
setTimeout(function(){
console.log(i);
},3000);
}
//5
//5
//5
//5
//5
上述代码由于var
是全局变量,因此console.log(i)
会输出5次最终i
的值5次
for(let i = 0; i < 5; i++){
setTimeout(function(){
console.log(i);
},3000)
}
//0
//1
//2
//3
//4
上述代码由于let
是局部变量,于是输出就是0,1,2,3,4,通过let
的方式就将原本需要闭包才能处理的问题给解决了。
3. 变量提升
let
命令不存在变量提升,let
命令只有在声明之后才能使用。
console.log(one); // undefined
var one = 1;
console.log(two); // ReferenceError
let two = 2;
由于var
存在变量提升,因此在未赋值的时候one
的值是undefined,而let
不存在变量提升,于是报错。
4. 暂时性死区
使用let
命令在代码块中声明就会使该代码块成为暂时性死区,任何在let
未声明之前的操作都会导致报错。
var item = 'item';
if(true){
item = 'other item'; // ReferenceError
let item;
}
上述代码在代码块中形成暂时性死区,所以对item变量的操作会导致报错。
5. 不允许重复声明
let
命令不允许在相同作用域内,重复声明同一个变量。
//报错
function func(){
let a = 10;
var a = 1;
}
//报错
function func(){
let a = 10;
let a = 1;
}
参考
本文参考阮一峰老师的ECMAScript 6 入门
本文只是简单记录let与var的区别,没有列举实际代码,只为以后更好回溯。