如何在闭包内访问“this”?

时间:2013-09-04 13:15:59

标签: javascript jquery closures

我是JavaScript和jQuery的新手,我遇到了一些代码问题。

HTML:

<div class="toggle" style="display: block; width: 200px; height: 200px; background-color: red;">test</div>

JavaScript的:

jQuery(document).ready(
    function()
    {
        jQuery(".toggle").on("click", function() {
            console.log("let the toggling begin!");

            jQuery(this).slideToggle(600, function(){ // slide up
                setTimeout(function(){ // wait 4 sec, then slide back down
                    jQuery(this).slideToggle(600)
                }, 4000);
            });
        });
    }
);

所以我的想法是你点击div,它会向上滑动,然后4秒后滑回。它不起作用。

JSFIDDLE:http://jsfiddle.net/zEqN9/2/

但是,如果我将每个闭包中的this更改为".toggle",那么它确实有效。

JSFIDDLE:http://jsfiddle.net/YZxMb/

很明显,问题在于我使用了this

我尝试将this作为参数传递给两个闭包函数中的每一个,但是这给出了错误Unexpected token this

如何从内部函数访问this变量?

6 个答案:

答案 0 :(得分:5)

在slideToggle函数中创建对this的引用。

 jQuery(document).ready(
    function()
    {
        jQuery(".toggle").on("click", function() {
            console.log("let the toggling begin!");

            jQuery(this).slideToggle(600, function(){ // slide up
                var self = this; // <-- notice this
                setTimeout(function(){ // wait 4 sec, then slide back down
                    jQuery(self).slideToggle(600)
                }, 4000);
            });
        });
    }
);

答案 1 :(得分:1)

使用bind为您希望在上下文之外调用的功能指定this

var foo = {
    bar: function () {
        setTimeout(function () { // though in a setTimeout
            console.log(this);
        }.bind(this), 0); // binding to `this` here means
    }
};

foo.bar(); // invoking it still has `this` of `foo`

答案 2 :(得分:0)

原因是对于jQuery事件,显式设置了函数的上下文,以便this引用目标元素 - 这是由jQuery完成的。但是,setTimeout的匿名函数没有为您设置上下文 - 它获取默认的全局上下文,因此this引用窗口。

您需要做的是获取对click事件的上下文的引用,然后在超时中使用引用:

jQuery(function () {
    jQuery(".toggle").on("click", function () {
        var $this = $(this);

        $this.slideToggle(600, function () { // slide up
            setTimeout(function () { // wait 4 sec, then slide back down
                $this.slideToggle(600);
            }, 4000);
        });
    });
});

然而,正如评论中所指出的,这可以写成:

jQuery(function () {
    jQuery(".toggle").click(function () {
        jQuery(this).slideToggle(600).delay(4000).slideToggle(600);
    });
});

答案 3 :(得分:0)

var yourThing = jQuery(this);

yourThing.slideToggle(600, function(){ // slide up
     setTimeout(function(){ // wait 4 sec, then slide back down
          yourThing.slideToggle(600)
     }, 4000);
});

答案 4 :(得分:0)

只需在代码中添加此行即可了解原因:

setTimeout(function(){ // wait 4 sec, then slide back down
      console.log(jQuery(this)); //this one
      jQuery(this).slideToggle(600)
      }, 4000);

打开你的控制台。您将看到,在setTimeout函数中,$(this)引用窗口对象。

答案 5 :(得分:0)

您需要创建对此的引用,因此当运行与setTimeout关联的函数时,您可以传递此引用。

 jQuery(document).ready(
        function()
        {
            jQuery(".toggle").on("click", function() {
                console.log("let the toggling begin!");
                var that = this; // <--- reference to this
                jQuery(this).slideToggle(600, function(){ // slide up
                    setTimeout(function(){ // wait 4 sec, then slide back down
                        jQuery(that).slideToggle(600)
                    }, 4000);
                });
            });
        }
    );