在学习Javascript的一开始,我们就使用var来创建变量,随着ES6的发布,出现了一个一个新的创建变量的方式let
,随着浏览器和node的快速支持以及babel的出现,我们已经可以正式使用let
。在很多情况下用于比起使用var
,let
会更好,不只是在代码的稳定性还可以增加代码的可读性。
我们在学习let
的时候,经常会看到对于let
的定义
The let statement declares a block scope local variable,optionally initializing it to a value.(let语句声明一个块级作用域的本地变量,并且可选的赋予初始值。) — let MDN
显而易见的,let
就是作用于块级作用域,那么我们首先来了解一下什么是块级作用域(block scope)。
对于块级作用域MDN的定义是
语句块 (或其他语言中的 复合语句) 用来组织零个或多条语句. 用一对花括号界定语句块. — block MDN
语法
1 | [label:] { |
MDN对于语法的说明,给了我们一个说明,下面while (x < 10)
也是块级作用域的一部分。
1 | while (x < 10) { |
所以简单来说let在{}
以内或者在类似while (x < 10)
的()
中定义的变量,不会被外层的作用域访问到,如下的例子
1 | if (true) { |
同时,我们看下面这个例子
1 | 'use strict'; |
这段代码也很好理解,我要说的是,我们一开始申明了'use strict';
,表示我们使用了严格模式,我们两次定义了a变量,但是代码正常执行了,说明了{}
产生了新的块作用域,所以代码正常执行了。
另外对于let
,我们可以看情况将其包裹在{}
中,为变量显式声明块作用域,这样更加符合let
的块级作用域的定义,也可以方便js的垃圾回收机制来判断是否需要回收,也可以增加代码的模块化和可读性,例子如下
1 | function process(data) { |
最后,我来解答一道网上经常看到的题目,题目和详细解答在我的另一篇文章中也有,我个人认为最好的答案是,只需要把var
改为let
,其实这道题目的本质在于var
不是块级作用域,而我们的代码是写在块级作用域中的,所以我们需要一个块级作用域的变量声明,保证每个块级作用域都是不一样的变量,相互不影响,而let
刚好。
1 | for ( let i=1; i<=5; i++) { |