如何让setTimeout在对象中执行方法?

时间:2010-02-21 12:10:58

标签: javascript oop settimeout

我希望在短暂的延迟后,在鼠标事件上关闭一个下拉菜单。但是我无法让它正常工作。

在对象中考虑以下方法:(我使用的是jQuery)

myObj = {};

myObj.message = "woot!";

myObj.bindEvents = function() {

        var that = this;

        $("#menuPanel")
            .bind("mouseleave", function() { 

                    that.timer = setTimeout(that.closeMenu,500); 

            });

    }

myObj.closeMenu = function() {

     // close the menu

     alert(this.message);

}

这不起作用。也就是说,this.message未定义。经过一番挖掘,我理解为什么。 :)'that'引用在执行时不能用于setTimeout内部的代码。

我想知道,解决此类问题的“最佳”方法是什么?我怎样才能有一个使用setTimeout的方法在同一个对象中调用另一个方法,并且仍然可以访问对象中的属性?

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

这里的问题是你要从它的对象中分离closeMenu方法。如果你这样做,你会遇到同样的问题:

var closeMenu = myObj.closeMenu;  // detaching the method from the object
closeMenu();

分离和调用这样的方法意味着它们不再适用于它们所创建的对象。在你的例子中,你做的几乎是同样的事情:

// Setting the first parameter of setTimeout to be the detached closeMenu method
that.timer = setTimeout(that.closeMenu,500); 

第一种方法的修正方法是使用callapply方法:

var closeMenu = myObj.closeMenu;  // detaching the method from the object
closeMenu.apply(myObj);

但这不适用于计时器。相反,创建一个匿名函数:

that.timer = setTimeout(function () { that.closeMenu(); },500); 

<小时/> 也许值得一提的是bind() - 不要与jQuery的$('#selector').bind()混淆 - 这种方法已经在各种博客和一些库中浮现(原型是最值得注意的)一段时间了,最终已在ECMAScript edition 5中实施。

that.timer = setTimeout(that.closeMenu.bind(that),500);

我在我创建的一个或两个类中使用了类似的方法,因为它只会让事情变得更容易。