firefox 下的闭包BUG
时间:2010-09-15 来源:华电混球
我在google上搜索 firefox 闭包 bug ,并没有搜索到好的一个说明和解释。
代码
<html>
<head>
<script type="text/javascript">
function onload(){
var mod = function(x,y){
return x%y;
};
var f_if = function(b, x, y){
return (b ? x : y);
};
var widget = function(color, li){
li = document.createElement('li');
li.innerText='Hello';
li.style.color = '#B7DCBB';
li.style.padding = '5px';
li.style.backgroundColor = color;
return li;
};
var ul = document.createElement('ul');
(function(i){
f_if(
i--,
function(i){
ul.appendChild(widget(f_if(mod(i,2),'#631853','#8D491C')));
arguments.callee.caller.arguments.callee(i);
},
function(){
document.body.appendChild(ul)
}
)(i);
})(10);
}
</script>
</head>
<body>
</body>
</html>
1. 在chrome\IE 下,这样定义function onload(){},并不会直接触发window.onload事件。需要一板一眼的window.onload=function(){}.
2.
在firefox下,这样的代码不会得到正确运行,聚焦到上面这样一行代码中,“ arguments.callee.caller.arguments.callee(i);”,截止到arguments.callee.caller 是会找到这个方法的,在ff中log也可以看到内容,但是却是没有arguments属性。
犯难,改代码“arguments.callee.caller(i)”。却显示找不到f_if 。在作用域下都找不到,没见过这个问题。
犯难,问师傅。师傅看了一下,可能换到window域下找方法和变量了,这个闭包有问题。于是改成
代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"0>
<title>test_function</title>
<script type="text/javascript" charset="utf-8">
window.onload=function(){
var mod = function(x,y){
return x%y;
};
var f_if = function(b, x, y){
return (b ? x : y);
};
var widget = function(color, li){
li = document.createElement('li');
li.appendChild(document.createTextNode('hello'))
li.style.color = '#B7DCBB';
li.style.padding = '5px';
li.style.backgroundColor = color;
return li;
};
var ul = document.createElement('ul');
var closeFun=function(i){
f_if(
i--,
function(i){
ul.appendChild(widget(f_if(mod(i,2),'#631853','#8D491C')));
arguments.callee.caller(i);
},
function(){
document.body.appendChild(ul)
}
)(i);
}
closeFun(10)
}
</script>
</head>
<body>
</body>
</html>
这是一段网上一位前辈留下的代码,为的是让人们尝试类函数式的js编程(别讨论是不是‘类’了,这个不重要)。重要是发现在FF中,闭包会引起作用域的变化。

<head>
<script type="text/javascript">
function onload(){
var mod = function(x,y){
return x%y;
};
var f_if = function(b, x, y){
return (b ? x : y);
};
var widget = function(color, li){
li = document.createElement('li');
li.innerText='Hello';
li.style.color = '#B7DCBB';
li.style.padding = '5px';
li.style.backgroundColor = color;
return li;
};
var ul = document.createElement('ul');
(function(i){
f_if(
i--,
function(i){
ul.appendChild(widget(f_if(mod(i,2),'#631853','#8D491C')));
arguments.callee.caller.arguments.callee(i);
},
function(){
document.body.appendChild(ul)
}
)(i);
})(10);
}
</script>
</head>
<body>
</body>
</html>
代码质量不错,我很受益匪浅,简洁明了。
但是问题也随之发生了:1. 在chrome\IE 下,这样定义function onload(){},并不会直接触发window.onload事件。需要一板一眼的window.onload=function(){}.
2.
在firefox下,这样的代码不会得到正确运行,聚焦到上面这样一行代码中,“ arguments.callee.caller.arguments.callee(i);”,截止到arguments.callee.caller 是会找到这个方法的,在ff中log也可以看到内容,但是却是没有arguments属性。
犯难,改代码“arguments.callee.caller(i)”。却显示找不到f_if 。在作用域下都找不到,没见过这个问题。
犯难,问师傅。师傅看了一下,可能换到window域下找方法和变量了,这个闭包有问题。于是改成

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"0>
<title>test_function</title>
<script type="text/javascript" charset="utf-8">
window.onload=function(){
var mod = function(x,y){
return x%y;
};
var f_if = function(b, x, y){
return (b ? x : y);
};
var widget = function(color, li){
li = document.createElement('li');
li.appendChild(document.createTextNode('hello'))
li.style.color = '#B7DCBB';
li.style.padding = '5px';
li.style.backgroundColor = color;
return li;
};
var ul = document.createElement('ul');
var closeFun=function(i){
f_if(
i--,
function(i){
ul.appendChild(widget(f_if(mod(i,2),'#631853','#8D491C')));
arguments.callee.caller(i);
},
function(){
document.body.appendChild(ul)
}
)(i);
}
closeFun(10)
}
</script>
</head>
<body>
</body>
</html>
在不使用闭包之后,问题解决。在IE 和 chrome下一直正常,所以我觉得应该是BUG,或者是ff在处理此类问题是有特殊的解决方式?
如果你知道,请点明我
相关阅读 更多 +