例行声明:接下来的文字内容全部来自 Understanding ECMAScript 6,作者是Nicholas C.Zakas,也就是大名鼎鼎的Professional JavaScript for Web Developers(《JavaScript高级程序设计》)的作者。我很喜欢他的写作风格,所以在看了Understanding ECMAScript 6后试着自己写篇博客梳理一下,相当于简单地翻译和巩固一下吧。在此特别感谢Nicholas的原创,我只是一个小矮人,站在巨人的肩膀上,所以看到了原本看不到的风景。
附上英文原文链接:https://leanpub.com/understan...
1: 背景介绍
在严谨模式下面,ES6之前,在一个block里面定义一个functoin是会抛出语法错误的,例如:
"use strict";
if (true) {
// Throws a syntax error in ES5, not so in ES6
function doSomething() {
// ...
}
}
在ES6,我们引入了块级函数,接下来看一下如何使用块级函数。
2: 如何定义一个 block-level function
'use strict';
if(true){
function a(){
//...
}
console.log(typeof a);//function
}
console.log(typeof a); //undefined
在if创建的一个块级作用域里面,我们定义了一个function a,然后在这个块级作用域里面执行typeof a
,得到结果function
,然后在if 创建的这个块级作用域外去执行typeof a
,得到结果为undifined
.这说明这个function a在其被定义的块级作用域里面可见,在这个块级作用域之外不可见。
3: block-level function的作用域提升
大家都知道,平常我们除了用1: function xx(){}
这种方式来定义一个function外,也可以采用function expression: 2: let xx = function(){}
.在用这两种方式来定义的block-level function在作用域提升
的表现方面是截然不同的: 第一种会提升,第二种不会。
,举例说明:
'use strict';
if(true){
console.log(typeof a)//function
function a(){
/...
}
}
'use strict';
if(true){
console.log(typeof a)// uncaught ReferenceError: a is not defined
let a = function(){
/...
}
}
从上面的对比可以看出,用let定义的function, 作用域不会提升,当执行typeof a的时候,抛出一个错误。这个本质上是let引起的临时死区的问题,具体可以参照变量的临时死区。
4: 在非严谨模式下block-level function的作用域
在前面的1,2, 3点,我们都是在严格模式下面的探讨。但是,block-level funciton的作用域提升
在严格模式和非严格模式下面的表现是不一样的。
4.1: 用 let xx = function(){}
也就是用function expression这种方式定义的block-level function在严格模式和非严格模式下表现一样:会抛出错误uncaught ReferenceError: xx is not defined
.所以不做过多讨论。
4.2: 现在来看一个用function xx(){}
的方式定义block-level funciton时的表现,且这个block是在另一个function里面
上图是在Chrome Version 55.0.2883.95下面执行的结果。
* 从执行结果来看只有output 2的结果是function,这个是我们之前已经讨论过了的在block内部的作用域提升。
* 结合ouput 1和output 3的结果来看,block-level function的作用域会被提升到整个 function,但只在其定义代码执行之后的区间。
* output 4的结果表明,此种场景下,作用域并不会被提升至global.
4.3 在global下面的block里面定义一个block-level function
从执行结果看来,此种场景下,作用域会被提升至global,但是也得是在其定义之后的区间,在其被定义的block之前的global区间之内,是不可见的。
所以我们可以做一个关于块级函数的作用域的完整的总结:
1: 对于function expression,无论在严格模式还是非严格模式下,作用域都不会提升,而且还有有临时死区的特征。
2: 对于定义形的块级函数,在严格模式下,作用域不会提升。
3: 对于定义形的块级函数,在非严格模式下,作用域会被提升;但是提升的区间为其最近的一层作用域内,且在其定义之后。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。