let是es6新增的命令,其用法和var差不多,但是还是有些区别的。
一、let是块级命令,var不是块级命令
{ let a = 1; var b = 2; } console.log(a); // ReferenceError: a is not defined console.log(b); // 2
同时在代码块里面声明a和b,但是在外面访问的时候只能访问b,说明let的作用域只是在块级里面,用let声明变量可以防止变量泄漏。
在for的循环遍历中就适合用let命令了
for (let i = 0; i < 10; i++) {} console.log(i); //ReferenceError: i is not defined
如果将上面的let换成var,就会输出10。
二、let不存在变量提升
console.log(foo); // 输出undefined console.log(bar); // 报错ReferenceError var foo = 2; let bar = 2;
上面的代码就可以看出let声明的变量是不存在变量提升的,所以必须先声明在使用,不然会报错的。
三、暂时性死区
只要在块级作用域中存在let命令,它所声明的变量就“绑定”在这个区域,不受外部影响
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
上面的代码中,虽然声明了全局的变量tmp,但是在块级作用域中也声明了tmp变量,所以导致tmp被绑定在块级作用域中,因此在声明之前访问tmp,会报ReferenceError的错。
ES6中规定,在若区块中方存在let和const命令,这个区块对这些命令声明的变量从一开始就形成了封闭作用域,凡是在声明之前使用这些变量就会报错。
四、不允许重复声明
// 报错 function () { let a = 10; var a = 1; } // 报错 Uncaught SyntaxError: Identifier 'a' has already been declared function () { let a = 10; let a = 1; } //Uncaught SyntaxError: Identifier 'a' has already been declared function () { var a = 10; var a = 1; } // 1
上面的代码可以看出let在同一作用域中不能重复声明,但是var可以,而且ar后面声明的值能覆盖前面的值。