【原】JavaScript 闭包

javascript 的闭包意思是说内部函数即使在外部函数执行完成并终止后仍然可以访问到其外部函数的属性

这回造成一些意想不到得错误, 看下边的代码:(转载 ITCAST签约讲师 姜浩 在javascript专题 中的代码)

test.html中的代码:

<html>
<head>
    <title>闭包</title>
    <script type="text/javascript" src="./script.js">
    </script>
    <style type="text/css" src="./style.css">
    </style>
</head>
<body>
    <p>闭包是一个作用域的相关概念, 
    是指内层函数在外层函数执行结束
    退出之后仍然能访问其属性</p>
    <a id="a_1">我是anchor1</a><br/>
    <a id="a_2">我是anchor1</a><br/>
    <a id="a_3">我是anchor1</a><br/>
</body>
</html>

script.js 中的文件:

window.onload=init;
 
function init()
{
    for (var step = 1; step != 4; ++ step)
    {
        var anchor = document.getElementById("a_" + step);
        anchor.onclick = (function ()
        {
            window.alert("你点击的是" + step);
        });
    }
}

这个页面打开后点击每个anchor都会弹出提示框显示:你点击的是4
这是因为在init函数执行的时候, 将每个anchor的onclick属性都设定为一个匿名函数, 循环完后step 的值是4
在用户点击每个anchor的时候, 运行的就是这个匿名函数, 这个函数首先在函数内部找step, 没有找到, 于是开始在他的父作用域里找, 注意, 这个时候由于闭包, 这个匿名函数仍然能看到上级函数中的step, 于是就出现上边的情况。

解决方法就是为每个anchor创建一个新的函数对象, 并将step传进去:

window.onload=init;
 
function init()
{
    for (var step = 1; step != 4; ++ step)
    {
        var anchor = document.getElementById("a_" + step);
        registListener(anchor, step);
    }
}
 
function registListener(element, step)
{
    element.onclick = (function ()
    {
        window.alert("你点击的是" + step);
    });
}

此时, 会有4个registListener。

此条目发表在 HTML/Javascript/CSS 分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>