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重写'); }
}
//在闭包内 (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