将正确的“this”上下文传递给 setTimeout 回调?
如何将上下文传递到 ?我想在1000毫秒后打电话。我该怎么做?setTimeout
this.tip.destroy()
this.options.destroyOnHide
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
当我尝试上述内容时,指的是窗口。this
如何将上下文传递到 ?我想在1000毫秒后打电话。我该怎么做?setTimeout
this.tip.destroy()
this.options.destroyOnHide
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
当我尝试上述内容时,指的是窗口。this
编辑:总之,早在2010年,当这个问题被问到这个问题时,解决这个问题的最常见方法是保存对进行函数调用的上下文的引用,因为执行函数时指向全局对象:setTimeout
setTimeout
this
var that = this;
if (this.options.destroyOnHide) {
setTimeout(function(){ that.tip.destroy() }, 1000);
}
在 ES5 规范中,在那之前一年刚刚发布,它引入了绑定
方法,这在最初的答案中没有建议,因为它尚未得到广泛支持,您需要 polyfill 才能使用它,但现在它无处不在:
if (this.options.destroyOnHide) {
setTimeout(function(){ this.tip.destroy() }.bind(this), 1000);
}
该函数创建一个预填充了值的新函数。bind
this
现在在现代JS中,这正是箭头函数在ES6中解决的问题:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy() }, 1000);
}
箭头函数没有自己的值,当您访问它时,您正在访问封闭词法作用域的值。this
this
HTML5 在 2011 年也对计时器进行了标准化,现在您可以将参数传递给回调函数:
if (this.options.destroyOnHide) {
setTimeout(function(that){ that.tip.destroy() }, 1000, this);
}
另请参阅:
有现成的快捷方式(语法糖)到函数包装器@CMS回答。(下面假设您想要的上下文是 .)this.tip
对于几乎所有的javascript开发(在2020年),你可以使用胖箭头函数,它们是ECMAScript 2015(Harmony/ES6/ES2015)规范的一部分。
与函数表达式相比,箭头函数表达式(也称为胖箭头函数)具有较短的语法,并且在词法上绑定值 [...]。
this
(param1, param2, ...rest) => { statements }
如果您的情况,请尝试以下操作:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy(); }, 1000);
}
如果您的目标是与 ECMA-262、第 5 版(ECMAScript 5)或 Node.js 兼容的浏览器(在 2020 年),这意味着所有常见的浏览器以及较旧的浏览器,则可以使用 Function.prototype.bind
。您可以选择传递任何函数参数来创建分部函数。
fun.bind(thisArg[, arg1[, arg2[, ...]]])
同样,在你的情况下,试试这个:
if (this.options.destroyOnHide) {
setTimeout(this.tip.destroy.bind(this.tip), 1000);
}
原型中也实现了相同的功能(还有其他库吗?
Function.prototype.bind
可以像这样实现,如果你想要自定义的向后兼容性(但请遵守注释)。
如果您已经在使用jQuery 1.4 +,则有一个现成的函数用于显式设置函数的上下文。this
jQuery.proxy():获取一个函数并返回一个始终具有特定上下文的新函数。
$.proxy(function, context[, additionalArguments])
如果您的情况,请尝试以下操作:
if (this.options.destroyOnHide) {
setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}
它在Underscore.js以及lodash中作为1,2提供_.bind(...)
捆将函数绑定到对象,这意味着每当调用函数时,的值将是对象。(可选)将参数绑定到函数以预填充它们,也称为部分应用程序。
this
_.bind(function, object, [*arguments])
如果您的情况,请尝试以下操作:
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}