Open JesseZhao1990 opened 6 years ago
我们知道ES6 新增了let命令,用来声明变量。它的用法类似于var。 但是和var还是有一些不同。下面我们总结一下let和var的不同之处
使用var的情况
console.log(foo); // undefined var foo="testtest";
使用let的情况
console.log(foo); let foo = "testtest"; // 报错,Uncaught ReferenceError: foo is not defined
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
第一种场景: 内层变量可能会覆盖外层变量
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'hello world'; } } f(); // undefined
上边的代码的本意是,if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量。但是,函数f执行后,输出的结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
第二种场景:用来计数的局部变量泄露成了全局变量
var str ="jessezhao"; for(var i=0;i<str.length;i++){ } console.log(i) // 9
块级作用域的出现,使得被广泛使用的立即执行函数表达式(IIFE)不再成为必须了。
// IIFE 写法 (function () { var tmp = ...; ... }()); // 块级作用域写法 { let tmp = ...; ... }
只要块级作用域内存在let命名,它所声明的变量就绑定(binging)在这个区域,不再受外部的影响
var tmp = 123; if (true) { tmp = 'abc'; // Uncaught ReferenceError: tmp is not defined let tmp; }
上边这个tmp = 'abc' 之所以报错,是因为在块级作用域中,在let命令声明之前,任何对tmp的引用都会报错。
var tmp = 123; if (true) { // 暂时性死区开始 tmp = 'abc'; // Uncaught ReferenceError: tmp is not defined let tmp; // 暂时性死区结束 }
function test(){ var a = 3; let a = 4; // Uncaught SyntaxError: Identifier 'a' has already been declared } test()
function test(){ let a = 3; let a = 4; // Uncaught SyntaxError: Identifier 'a' has already been declared } test()
我们知道ES6 新增了let命令,用来声明变量。它的用法类似于var。 但是和var还是有一些不同。下面我们总结一下let和var的不同之处
1. 不存在变量提升
使用var的情况
使用let的情况
2. 块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
第一种场景: 内层变量可能会覆盖外层变量
上边的代码的本意是,if代码块的外部使用外层的tmp变量,内部使用内层的tmp变量。但是,函数f执行后,输出的结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
第二种场景:用来计数的局部变量泄露成了全局变量
块级作用域的出现,使得被广泛使用的立即执行函数表达式(IIFE)不再成为必须了。
3. 暂时性死区
只要块级作用域内存在let命名,它所声明的变量就绑定(binging)在这个区域,不再受外部的影响
上边这个tmp = 'abc' 之所以报错,是因为在块级作用域中,在let命令声明之前,任何对tmp的引用都会报错。
4. 不允许重复声明