我已声明了divHandler fn,然后将其附加到onclick事件。
在阅读了闭包之后,我理解divHandler可以访问封闭的环境,在这种情况下是一个附加到onload事件的函数。所以divHandler应该可以访问初始化为0的cnt var。
但是当我点击执行div时,我得到Uncaught reference error: cnt is not defined
我不明白这怎么可能?请帮我解决一下这个。感谢。
<script>
function divHandler(e){
++cnt;
document.getElementById("d1_cnt").innerHTML=" clicked "+ cnt + " times...";
}
window.onload=function() {
var cnt=0;
document.getElementById("d1").onclick=divHandler;
}
</script>
<body>
<div id="d1">Div click me</div><span id="d1_cnt"></span>
</body>
答案 0 :(得分:3)
因为cnt
是您分配给onload
的函数中的本地变量,而divHandler
并未关闭它。就像这样:
function foo() {
var a = 42;
}
// Can't access `a` here.
相反,将cnt
移到divHandler
可以关闭它的位置 - 但如果您不需要,请不要将其设为全局:
(function() {
var cnt = 0;
function divHandler(e){
++cnt;
document.getElementById("d1_cnt").innerHTML=" clicked "+ cnt + " times...";
}
window.onload=function() {
document.getElementById("d1").onclick=divHandler;
}
})();
请注意,我使用该代码的作用域功能也使divHandler
不再是全局的,因为(除非你没有显示的内容),没有理由这样做。
或者实际上,您可以将其全部放在onload
:
window.onload=function() {
var cnt = 0;
function divHandler(e){
++cnt;
document.getElementById("d1_cnt").innerHTML=" clicked "+ cnt + " times...";
}
document.getElementById("d1").onclick=divHandler;
};
旁注:在所有图片和其他外部资源完全加载(或失败)后,window.load
事件在页面加载周期的后期发生非常。您无需等待那么长时间来连接您的点击处理程序。只需确保您的script
元素在下面您希望它在HTML中使用的元素的标记,您就可以立即连接处理程序。通常的建议是在结束</body>
标记之前放置脚本,因为这意味着他们可以访问它们上面的所有内容。
<body>
<div id="d1">Div click me</div><span id="d1_cnt"></span>
<script>
(function() {
var cnt = 0;
function divHandler(e){
++cnt;
document.getElementById("d1_cnt").innerHTML=" clicked "+ cnt + " times...";
}
document.getElementById("d1").onclick=divHandler;
})();
</script>
</body>
答案 1 :(得分:0)
范围基于变量/函数声明的位置而不是它们被分配的位置。
var cnt
将变量范围限定为在其中定义的(匿名)函数。
函数divHandler
未在该函数内声明,因此它无法访问该变量。
在匿名函数表达式中移动divHandler
函数声明。
答案 2 :(得分:0)
我发现你错过了理解
Closure上的此StackOverflow链接将帮助您更好地理解