如何访问“;这个“;在封闭物内

How to access "this" inside a closure?

本文关键字:这个 何访问 访问      更新时间:2023-09-26

我是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变量?

在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);
            });
        });
    }
);

使用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`
var yourThing = jQuery(this);
yourThing.slideToggle(600, function(){ // slide up
     setTimeout(function(){ // wait 4 sec, then slide back down
          yourThing.slideToggle(600)
     }, 4000);
});

只需在代码中添加这一行即可理解原因:

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

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

您需要创建一个对此的引用,因此当运行与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);
                });
            });
        }
    );

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

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

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);
    });
});