最近在看ES6 的书的时候发现了这样一段代码, 将的是块级作用域的问题
function f() { console.log('I am outside!'); }
(function () {
if(false) {
// 重复声明一次函数f
function f() { console.log('I am inside!'); }
}
f();
}());
上面代码在ES5中运行,会得到“I am inside!”,但是在ES6中运行,会得到“I am outside!”。这是因为ES5存在函数提升,不管会不会进入 if代码块,函数声明都会提升到当前作用域的顶部,得到执行;而ES6支持块级作用域,不管会不会进入if代码块,其内部声明的函数皆不会影响到作用域的外部。
然后我运行了一下,发现报错了,
Uncaught TypeError: f is not a function
这说明函数 f 的声明并没有被提升到if语句的外面, 也就是自执行函数作用域的最顶部
然后我研究了一下,
function f() { console.log('I am outside!'); }
(function () {
if(false) {
// 重复声明一次函数f
function f() { console.log('I am inside!'); }
}
console.log( f ); //undefined
}());
浏览器输出的 f 是 undefined, 说明 f 被声明了
多方查证之后得出结论:
if 条件句中的 function 会被编译成 函数表达式, 声明会被提升到当前作用域的最顶部, 但是赋值会被留在原地. 这也就解释了为什么我们打印 f 的时候会是 undefined 而不是报错, 当然, 如果 if 条件改为 true, f 函数会完成赋值, 最终也是可以调用的
function f() { console.log('I am outside!'); }
(function () {
if (true) {
// 重复声明一次函数f
function f() { console.log('I am inside!'); }
}
f(); // I am inside!
}());