废话少说,直接上题:

        f = function() {return true;};   
        g = function() {return false;};   
        (function() {   
           if (g() && [] == ![]) {   
              f = function f() {return false;};   
              function g() {return true;}   
           }   
        })();   
        alert(f()); // ?

这道题之所以坑,是因为网上有不同的答案,婆说婆有理!总体概括为以下三个答案:
答案一:第四行“g()”报错;
答案二:false;
答案三:true;
最后经本人亲自证实发现了这道题最坑的地方,三个答案都是对的,不过在不同的浏览器中!如下:

/**
  * edge ie11 chrome(较新版) fireFox(较新版) 第四行g()报错(Uncaught TypeError:g is not a function)
  * ie10 ie9 答案为:false
  * ie8及以下 答案为:true
  */

下面来看看网友们的解释:
答案一:与判断条件无关,js解析器对自调用函数中的函数g进行了预编译但因为在条件中语句还未执行而去提前调用,所以造成报错。
即使写成如下代码也是如此:

        function g() {return false;};   
        function h() {   
            console.log(g);//undefined
           if (g()) {     
              function g() {return true;}   
           }   
        }   
        h();
        //edge ie11 chrome(较新版) fireFox(较新版) 第四行g()报错(Uncaught TypeError:g is not a function)

答案二:

(function() {     

   if (g() && [] == ![]) {     

//应该看成if((g() && [] )== ![])   

//因为g()是false后面那个&&[]就没起作用 整个都是false    

//![]也是false 所以if成立 进入if块内   

      f = function f() {return false;};     

//重新定义f    

      function g() {return true;}     

//这句没用   

   }     

})();    

alert(f());   

//false  

答案三:

        f = function() {return true;};   
        g = function() {return false;};   
        (function() {
            //g() 返回false,==优先级高于&&,&&后直接忽略,条件判断不成立。   
           if (g() && [] == ![]) {   
              f = function f() {return false;};   
              function g() {return true;}   
           }   
        })();   
        alert(f()); // true

简直巨坑,貌似都很有道理!
在下不才,将造成这个问题的原因归咎为不同浏览器的js引擎对函数声明顺序的解析不同,如有更深见解,还请大神不吝赐教。


本文转载:CSDN博客