将正确的“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闭包(使用$.proxy
或Function.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);