Tra*_*vis 3 javascript oop settimeout
我想让一个下拉菜单在发生 mouseleave 事件时关闭,经过短暂的延迟。但我很难让它工作。
考虑对象中的以下方法:(我正在使用 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);
}
Run Code Online (Sandbox Code Playgroud)
这不起作用。也就是说, this.message 出现未定义。经过一番挖掘,我明白了为什么。:) 'that' 引用在执行时对 setTimeout 内的代码不可用。
我想知道,解决此类问题的“最佳”方法是什么?如何让使用 setTimeout 的方法调用同一个对象中的另一个方法,并且仍然可以访问对象中的属性?
在此先感谢您的帮助。
这里的问题是你正在从它的对象中分离 closeMenu 方法。如果你这样做,你会遇到同样的问题:
var closeMenu = myObj.closeMenu; // detaching the method from the object
closeMenu();
Run Code Online (Sandbox Code Playgroud)
像这样分离和调用方法意味着它们不再适用于创建它们的对象。在您的示例中,您几乎在做同样的事情:
// Setting the first parameter of setTimeout to be the detached closeMenu method
that.timer = setTimeout(that.closeMenu,500);
Run Code Online (Sandbox Code Playgroud)
第一种方法的修复方法是使用callorapply方法:
var closeMenu = myObj.closeMenu; // detaching the method from the object
closeMenu.apply(myObj);
Run Code Online (Sandbox Code Playgroud)
但这不适用于计时器。相反,创建一个匿名函数:
that.timer = setTimeout(function () { that.closeMenu(); },500);
Run Code Online (Sandbox Code Playgroud)
bind()——不要与 jQuery 混淆$('#selector').bind()——这种方法已经在各种博客和一些库(Prototype 是最显着的)中流传了一段时间,并最终在ECMAScript 版本 5 中实现。
that.timer = setTimeout(that.closeMenu.bind(that),500);
Run Code Online (Sandbox Code Playgroud)
我在我创建的一两个类中使用了类似的方法,因为它只是让事情变得更容易。