let and const
问题1: 块不是作用域
js函数中,var
定义的变量作用域是整个函数体。
变量的作用域不止于定义它的代码块,而是整个函数。
声明提前问题。
问题2:变量在循环中过度分享
let
即新的var
区别:
let
声明的变量作用域是块。let
也有声明提前问题,但不是随意的。- 全局
let
变量不是全局对象的属性。 不能用window.variableName
获取到。它们存在于一个隐藏的块中,理论上包含所有运行在web上的js代码。 for (let x...)
每次迭代创建一个与x的新的绑定。 如果for (let...)
循环执行多次,这个循环包含一个闭包,每个闭包会捕获一个不同的循环变量副本,而不是每个闭包捕获同样的循环变量。for-of
,for-in
和有分号的和c类似的,都是一样的作用。- 在声明之前使用
let
变量会报错。 直到控制流到达声明变量的那一行,代码都是未初始化的。 这条规则帮助找到bug。与返回NaN
结果相对,我们会在有问题的那行代码获得一个异常。 - 用
let
重新声明一个变量会报SyntaxError
。
注意:class
声明与let
行为相似,而非var
。如果你多次加载一个含某class
的代码,第二次会得到一个错误,因为你重新声明了这个类。
const
const
声明的变量和let
相似,不过不能给它们重新赋值,报SyntaxError
。
声明的时候必须赋值,不然也会报SyntaxError
。
命名空间
ES3之前,js只有全局和函数作用域。
ES3引入了try-catch
语句,意味着引入了一种新的作用域,只作用于catch
块的异常值。
ES5添加了一个使用eval()
的作用域。
ES6添加了块作用域,循环作用域,全局let
作用域,模块作用域,评估参数默认值的额外作用域。