将正确的“this”上下文传递给setTimeoutcallback函数?

如何将上下文传递给setTimeout ? 我想调用this.tip.destroy()如果this.options.destroyOnHide 1000毫秒后。 我怎样才能做到这一点?

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

当我尝试以上时, this是指窗口。

您需要保存对setTimeout函数调用所在的上下文的引用,因为setTimeout执行指向全局对象的函数:

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

您可以很容易地certificatesetTimeout通过this将其设置为全局对象:

 (function () { alert(this); // alerts hello setTimeout(function(){ alert(this == window); // true }, 1000); }).call("hello"); 

也可以看看:

  • setTimeout – “这个”的问题

有现成的快捷键(语法糖)的function包装@CMS回答。 (下面假设你想要的上下文是this.tip 。)


ECMAScript 5 ( 当前浏览器 ,Node.js)和Prototype.js

如果您的浏览器兼容ECMA-262,第5版(ECMAScript 5)或Node.js ,则可以使用Function.prototype.bind 。 您可以select传递任何函数参数来创build部分函数 。

 fun.bind(thisArg[, arg1[, arg2[, ...]]]) 

再次,在你的情况下,试试这个:

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

在Prototype中也实现了相同的function(任何其他库?)。

如果你想自定义向后兼容性(但请注意), Function.prototype.bind可以像这样实现 。


ECMAScript 2015 ( 一些浏览器 ,Node.js 5.0.0+)

对于尖端开发(2015年),您可以使用胖箭头function ,这是ECMAScript 2015(Harmony / ES6 / ES2015)规范 ( 示例 )的一部分。

函数expression式相比, 箭头函数expression式 (也称为胖箭头函数 )具有更短的语法,并在词汇上绑定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 , lodash

它可以在Underscore.js,以及lodash,如_.bind(...) 1,2

绑定将一个函数绑定到一个对象,这意味着无论何时调用该函数,这个值都将是该对象。 可选地,将参数绑定到函数以预填充它们,也称为部分应用程序。

 _.bind(function, object, [*arguments]) 

在你的情况下,试试这个:

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

绑定 jquery underscore.js ecmascript-5 prototypejs node.js

在Internet Explorer以外的浏览器中,可以在延迟后一起将parameter passing给函数:

 var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]); 

所以,你可以这样做:

 var timeoutID = window.setTimeout(function (self) { console.log(self); }, 500, this); 

性能方面比范围查找更好(将其caching到超时/间隔expression式以外的variables中),然后创build闭包(使用$.proxyFunction.prototype.bind )。

从Webreflection使它在IE中工作的代码:

 /*@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); } }); @*/ 

如果你使用underscore ,你可以使用bind

例如

 if (this.options.destroyOnHide) { setTimeout(_.bind(this.tip.destroy, this), 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);