如何修复我的jQuery代码中的闭包bug

时间:2013-12-24 07:58:09

标签: javascript jquery closures

每当我点击btn1或btn2时,页面始终会提醒“btn2”。似乎问题导致“点击”关闭。但我不知道如何修复它。

提前感谢。

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>untitled</title>
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script>
        (function(){
            $.fn.test =  function(){
                F.init.apply(this,arguments)
            };
            var F ={
                that:null,
                init:function(){
                    F.that = this;
                    $(F.that).click(function(e) {
                        F.method();
                    });
                },
                method:function(){
                    var text =$(F.that).html();
                    alert(text);
                }
            }
        })();
        $(function(){
            $("#btn1").test(); //alert btn2---bug
            $("#btn2").test(); //alert btn2
        });
    </script>
</head>
<body>
    <button id="btn1">btn1</button>
    <button id="btn2">btn2</button>
</body>
</html>

2 个答案:

答案 0 :(得分:3)

您已在班级中使用该名称引用了您的对象类F

因此,您的第F.that = this行有效地创建了其他OO语言中被视为“静态成员”的内容。该类,因此#btn2#btn1最终共享同一个that成员。

此外,您的点击处理程序正在尝试调用F.method() - 实际上也是一个静态方法调用。

每当您希望将其包裹在元素周围时,您需要创建类型为new F 对象。只有这样,您才能为每个元素单独this

我建议使用现成的jQuery插件模型,例如http://jqueryboilerplate.com/,而不是尝试创建自己的。从该代码中查看此摘录:

$.fn[ pluginName ] = function ( options ) {
    return this.each(function() {
        if ( !$.data( this, "plugin_" + pluginName ) ) {
            $.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
        }
    });
};

请注意它如何使用new Plugin创建插件实例,然后使用$.data将其存储在元素上,但仅在第一次针对每个元素调用插件时。

答案 1 :(得分:0)

1)F是静态对象

2)所以F.that也是静态的

3)所以

F.that = this 

行会将'this'设置为F.that。 4)第一次打电话

$("#btn1").test(); 

然后F.that将等于$(“#btn1”); //这将等于$(“#btn1”)

5)下次你打电话

$("#btn2").test();

然后F.that将等于$(“#btn2”); //这将等于$(“#btn2”)

6)最后到F.你正在设置$(“#btn2”)

7)因此$(F.that).html();本质上是$($(“#btn2”)。html()),它与$(“#btn2”)相同.html()

8)因此警报显示“btn2”