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

 

posted @ 2017-09-10 11:03  lastnigtic  阅读(1135)  评论(0编辑  收藏  举报