猿问

将正确的“此”上下文传递给setTimeout回调?[复本]

将正确的“此”上下文传递给setTimeout回调?[复本]

如何将上下文传递给setTimeout?我想打电话this.tip.destroy()如果this.options.destroyOnHide1000毫秒后。我怎么能这么做?

if (this.options.destroyOnHide) {
     setTimeout(function() { this.tip.destroy() }, 1000);}

当我尝试以上的方法时,this指的是窗户。


aluckdog
浏览 477回答 2
2回答

牛魔王的故事

编辑:总之,早在2010年这个问题被问到的时候,解决这个问题最常见的方法就是保存对setTimeout函数调用,因为setTimeout使用this指向全局对象:var that = this;if (this.options.destroyOnHide) {      setTimeout(function(){that.tip.destroy()}, 1000);}在ES5规范中,刚刚发布了一年前,它引入了bind方法在最初的答案中并没有提到这一点,因为它还没有得到广泛的支持,而且您需要使用多填充技术,但是现在它无处不在了:if (this.options.destroyOnHide) {      setTimeout(function(){ that.tip.destroy() }.bind(this), 1000);}这个bind函数创建一个新函数。this值预填充。在现代JS中,这正是箭头函数解决的问题。ES6:if (this.options.destroyOnHide) {      setTimeout(() => { that.tip.destroy() }, 1000);}箭头函数没有this值,当您访问它时,您将访问this包围词法范围的值。HTML 5也标准化定时器回到2011年,您可以将现在的参数传递给回调函数:if (this.options.destroyOnHide) {      setTimeout(function(that){that.tip.destroy()}, 1000, this);}

德玛西亚99

有现成的快捷键(语法糖)的功能包装@CMS回答。(下面假设您想要的上下文是this.tip.)ECMAScript 5 (当前浏览器、Node.js)和Prototype.js如果你的目标是兼容ECMA-262的浏览器,第5版(ECMAScript 5)或Node.js,你可以用Function.prototype.bind..您可以选择传递要创建的任何函数参数。部分函数.fun.bind(thisArg[, arg1[, arg2[, ...]]])同样,在您的例子中,请尝试如下:if (this.options.destroyOnHide) {     setTimeout(this.tip.destroy.bind(this.tip), 1000);}同样的功能原型实现(还有其他图书馆吗?)Function.prototype.bind可以像这样实现如果您希望自定义向后兼容(但请注意)。ECMAScript 2015 (一些浏览器、Node.js 5.0.0+)对于尖端开发(2015),您可以使用脂肪箭头函数,它们是ECMAScript 2015(和谐/ES6/ES 2015)规范的一部分 (实例).阿箭头函数表达式(亦称脂肪箭头功能)具有比函数表达式更短的语法,并且在词汇上绑定this价值[.](param1, param2, ...rest) => { statements }在您的情况下,尝试如下:if (this.options.destroyOnHide) {     setTimeout(() => { this.tip.destroy(); }, 1000);}jQuery如果您已经在使用jQuery 1.4+,那么就有一个现成的函数可以显式地设置this函数的上下文。jQuery.Proxy()*获取一个函数并返回一个始终具有特定上下文的新函数。$.proxy(function, context[, additionalArguments])在您的情况下,尝试如下:if (this.options.destroyOnHide) {     setTimeout($.proxy(this.tip.destroy, this.tip), 1000);}Underscore.js, 房客它可以在Underscore.js中获得,还可以作为_.bind(...)1,2绑定将函数绑定到对象,这意味着每当调用该函数时,this将成为目标。或者,将参数绑定到函数以预先填充它们,也称为部分应用程序。_.bind(function, object, [*arguments])在您的情况下,尝试如下:if (this.options.destroyOnHide) {     setTimeout(_.bind(this.tip.destroy, this.tip), 1000);}
随时随地看视频慕课网APP
我要回答