1、var有变量提升,let没有
console.log(a);
var a = 3;
这段代码会输出undefined,因为变量和函数的声明会被提前到最前面,它的执行相当于
var a;
console.log(a);
a = 3;
而使用let/const声明变量时,不存在变量提升机制,同样的代码会报错。
console.log(a); // Cannot access 'a' before initialization
let a = 2;
这也被称为let和const的暂时性死区,在变量声明前无法使用该变量。
2、var允许重复声明,let不允许
用var重复声明同一个变量,js执行时会忽略掉;
用let重复声明同一个变量,会报错变量已被声明。
3、创建全局变量时对顶层对象的处理不同
创建全局变量a时,var会在顶层对象中增加对应变量属性(在浏览器环境是window,在node环境是global),后续可以用window.a访问到同一个变量;
let就只是创建了全局变量,window不会发生变化。
4、let只在当前块级作用域内能被访问
这也是let最大的优势,在{}块级作用域中用let声明的变量,都只能在其中被访问。
function fn1() {
var a = 0
let b = 0
{
var c = 1
let d = 1
}
function fn() {
console.log('a: ', a); // 0
console.log('b: ', b); // 0
console.log('c: ', c); // 1
console.log('d: ', d); // not defined
}
fn()
}
if else语句和for循环都会创建块级作用域,for循环中使用let声明,声明的值就只会在当前循环的块级作用域内访问,不会被其她次循环影响到。
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i); // 01234
}, 0);
}
for (var i = 0; i < 5; i++) {
setTimeout(() => { // 会在最后执行
console.log(i); // 55555
}, 0);
}