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 ?
在IE678中
f = function() { return true; }; g = function() { return false; }; (function() { //IE中命名函数表达式存在bug,占两份内存, //右边部分会被当成函数声明被吊起到当前作用域顶端 function _f() { return false; }; //函数声明被吊起到当前作用域顶端 function _g() { return true; } //[] == ![] 这里主要是考究内部函数ToPrimitive //http://www.cnblogs.com/rubylouvre/archive/2010/10/02/1841143.html if (_g() && [] == ![]) { _f = function _f() { return false; }; } })(); alert(f());//true
在FF中(这里有点意思)
f = function() { return true; }; g = function() { return false; }; (function() { //FF的函数声明不会吊起到当前作用域顶端,因此这里的g为全局作用域的g,无法进入if分支 if (g() && [] == ![]) { f = function f() { return false; }; function g() { return true; } } })(); alert(f()); //true
下面是测试代码,证明FF不会吊起函数声明。
//by 司徒正美 //在闭包内 (function(){ alert(aaa); if(false){ var aaa = "aaa" } })(); (function(){ try{ alert(bbb); }catch(e){ alert("发生异常!!") } if(false){ function bbb(){ return "bbb" } } })(); //在全局作用域下 function ccc() { alert('ccc'); } ccc(); if(false) { function ccc() { alert('ccc重写'); } } function ddd() { alert('ddd'); } ddd(); if(true) { function ddd() { alert('ddd重写'); } }
FF这种行为搞得好像存在块作用域似的,难道又是为了追求速度而不愿修正的bug吗?!
在safari5,opera10,chrome6
f = function() { return true; }; g = function() { return false; }; (function() { function _g() { return true; }//被吊起 if (_g() && [] == ![]) { f = function() { return false; };//重写全局函数f } })(); alert(f()); // false