let
对于声明变量,let 相比 var 有几点不同之处:
- let 在同一作用域内,不能重复声明变量
- let 有块级作用域
- let 不存在变量提升
- let 声明的全局变量不是全局对象的属性(不能通过 window、this 访问)
函数的作用域
函数参数拥有各自的作用域和暂时性死区,与函数体的作用域相分离,这意味着参数的 默认值不允许访问在函数体内部声明的任意变量。——《深入理解ES6》
function fn(b, c) {
let b;
}
fn();以上代码会报错 "Identifier 'b' has already been declared",说明函数参数与函数体属于同一个作用域。难道该书的作者说错了?
我又看到另一种说法:
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。——《ECMAScript 6 入门》
到底哪种说法更靠谱,测试一下。
a 处于全局作用域,b、c、d 都处于本地作用域,也就是说,函数参数与函数体是同一个作用域。
再设置参数默认值:
可以看到,b、c 同处于本地作用域,而函数体内的 d 处于另外一个块级作用域。所以确实是参数默认值导致参数形成了一个单独的作用域。但在函数体内重新用 let 声明参数会报错,只能认为“等到初始化结束,这个作用域就会消失”。因此,《ECMAScript 6 入门》的说法更靠谱。