我如何传递上下文到setTimeout?如果this.options.destroyOnHide在1000毫秒后,我想调用this.tip.destroy()。我该怎么做呢?
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
当我尝试上面的时候,这指的是窗口。
我如何传递上下文到setTimeout?如果this.options.destroyOnHide在1000毫秒后,我想调用this.tip.destroy()。我该怎么做呢?
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
当我尝试上面的时候,这指的是窗口。
当前回答
注意:这将不能在IE中工作
var ob = {
p: "ob.p"
}
var p = "window.p";
setTimeout(function(){
console.log(this.p); // will print "window.p"
},1000);
setTimeout(function(){
console.log(this.p); // will print "ob.p"
}.bind(ob),1000);
其他回答
在ie以外的浏览器中,你可以在延迟后将参数一起传递给函数:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
你可以这样做:
var timeoutID = window.setTimeout(function (self) {
console.log(self);
}, 500, this);
就性能而言,这比作用域查找(将其缓存到timeout / interval表达式之外的变量中),然后创建闭包(通过使用$。proxy或Function.prototype.bind)。
代码使它在ie工作从Webreflection:
/*@cc_on
(function (modifierFn) {
// you have to invoke it as `window`'s property so, `window.setTimeout`
window.setTimeout = modifierFn(window.setTimeout);
window.setInterval = modifierFn(window.setInterval);
})(function (originalTimerFn) {
return function (callback, timeout){
var args = [].slice.call(arguments, 2);
return originalTimerFn(function () {
callback.apply(this, args)
}, timeout);
}
});
@*/
如果你使用下划线,你可以使用bind。
E.g.
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this), 1000);
}
如果你使用的是TypeScript,你可以将函数作为参数传递,就像这样:
setTimeout(this.tip.destroy, 1000);
this context会被赋值就像你在JavaScript的箭头函数中封装调用一样。
注意:这将不能在IE中工作
var ob = {
p: "ob.p"
}
var p = "window.p";
setTimeout(function(){
console.log(this.p); // will print "window.p"
},1000);
setTimeout(function(){
console.log(this.p); // will print "ob.p"
}.bind(ob),1000);
编辑:总之,早在2010年,当这个问题被问到时,解决这个问题最常见的方法是保存一个引用到setTimeout函数调用的上下文,因为setTimeout执行函数时指向全局对象:
var that = this;
if (this.options.destroyOnHide) {
setTimeout(function(){ that.tip.destroy() }, 1000);
}
在一年前发布的ES5规范中,它引入了bind方法,这在最初的答案中没有被建议,因为它还没有被广泛支持,你需要填充程序才能使用它,但现在它无处不在:
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);
}
参见:
setTimeout -“this”问题