ES6引入了块级作用域,明确允许在块级作用域之中声明函数
块级作用域之中,函数声明语句的行为类似于let
,在块级作用域之外不可引用
但实际上为了减轻因此产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
其规则为:
- 允许在块级作用域内声明函数。
- 函数声明类似于
var
,即会提升到全局作用域或函数作用域的头部。 - 同时,函数声明还会提升到所在的块级作用域的头部。
报错信息是个类型错误,f 不是函数类型
事实上,根据es6在作用域中声明函数的规则,他的实际运行顺序如下:
function f() { console.log('I am outside!'); }
(function () {
var f = undefined; // 函数声明提升至函数作用域(或全局)的头部,赋值undefined
if (false) {
// 函数声明提升到所在的块级作用域的头部并赋值下面函数
function f() { console.log('I am inside!'); }
}
f(); // 真正的函数声明未执行,此时f为undefined
}());
上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let
处理。
考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。