if与立即执行函数(IIFE)里面的变量提升
今天遇到一道笔试题,题目是这样的
f = function() {return true;}; g = function() {return false;}; (function() { if (g() && [] == ![]) { f = function f() {return false;}; function g() {return true;} } })(); alert(f()); // true or false ?
直接粘贴到浏览器运行会报错
g is not a function
奇怪了,按理说,就算外部g被覆盖,function的声明方式也应该是提升并立即赋值的,我决定重新梳理一下这方面的知识
二、实验
console.log(bar); // undefined console.log(foo); // error: foo is not defined if(true){ foo = 'foo'; function bar(){ return 'bar'; } }
如果我们给if中的foo加上var关键字
console.log(bar); // undefined IE11之前都会把bar赋值好 console.log(foo); // undefined if(true){ var foo = 'foo'; function bar(){ return 'bar'; } }
说明IE11之后(至多在firefox55,chorme60之后),if 里面的 var 和 function的声明方式,都会存在变量提升,但是并不赋值
在立即执行函数里面呢
console.log(bar); // error: bar is not defined console.log(foo); // error: foo is not defined (function(){ foo = 'foo'; function bar(){ return 'bar'; } }())
无论是各个版本的IE还是chrome,firefox都报错,说明 立即执行函数是一个函数作用域
我们在回过头来看这道题
f = function() {return true;}; g = function() {return false;}; (function() { if (g() && [] == ![]) { f = function f() {return false;}; // 还是外部的 f function g() {return true;} // 变量提升,但是不赋值,并且覆盖外部 g } })(); alert(f()); // IE11以前返回false