为什么这个关闭不起作用?

时间:2014-07-25 12:01:03

标签: javascript

我已声明了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>

3 个答案:

答案 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)

我发现你错过了理解

  1. 本地变量与全局变量
  2. 关闭范围
  3. Closure上的此StackOverflow链接将帮助您更好地理解