Javascript “正确通过”;这";设置超时回调的上下文?
如何将上下文传递到Javascript “正确通过”;这";设置超时回调的上下文?,javascript,callback,this,settimeout,bind,jquery,underscore.js,ecmascript-5,prototypejs,node.js,Javascript,Callback,This,Settimeout,Bind,Jquery,Underscore.js,Ecmascript 5,Prototypejs,Node.js,如何将上下文传递到setTimeout?我想在1000毫秒后调用this.tip.destroy() if (this.options.destroyOnHide) { setTimeout(function() { this.tip.destroy() }, 1000); } 当我尝试上面的方法时,这个指的是窗口。编辑:总之,在2010年,当我问这个问题时,解决这个问题最常见的方法是保存对执行设置超时函数调用的上下文的引用,因为setTimeout执行函数时this指向全局对象:
setTimeout
?我想在1000毫秒后调用this.tip.destroy()
if (this.options.destroyOnHide) {
setTimeout(function() { this.tip.destroy() }, 1000);
}
当我尝试上面的方法时,这个
指的是窗口。编辑:总之,在2010年,当我问这个问题时,解决这个问题最常见的方法是保存对执行设置超时
函数调用的上下文的引用,因为setTimeout
执行函数时this
指向全局对象:
var that = this;
if (this.options.destroyOnHide) {
setTimeout(function(){ that.tip.destroy() }, 1000);
}
在一年前刚刚发布的ES5规范中,它引入了,这在原始答案中没有提出,因为它还没有得到广泛支持,您需要使用polyfills,但现在它无处不在:
if (this.options.destroyOnHide) {
setTimeout(function(){ this.tip.destroy() }.bind(this), 1000);
}
bind
函数创建一个新函数,其中预先填充了此值
现在在现代JS中,这正是箭头函数解决的问题:
箭头函数本身没有this
值,当您访问它时,您正在访问封闭词法范围的this
值
HTML5也出现在2011年,现在可以将参数传递给回调函数:
if (this.options.destroyOnHide) {
setTimeout(function(that){ that.tip.destroy() }, 1000, this);
}
另见:
有现成的快捷方式(语法糖)可以连接到函数wrapper@CMS。(下面假设您想要的上下文是this.tip
)
(,Node.js 5.0.0+)
对于几乎所有的javascript开发(2020年),您都可以使用fat-arrow函数,它们是
与函数表达式相比,(也称为胖箭头函数)具有更短的语法,并且在词汇上绑定this
值[…]
在您的情况下,请尝试以下方法:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy(); }, 1000);
}
if (this.options.destroyOnHide) {
setTimeout(this.tip.destroy.bind(this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}
(,Node.js)和Prototype.js
如果您的目标是或(2020年),这意味着所有常见浏览器以及旧浏览器,您可以使用。您可以选择传递任何要创建的函数参数
同样,在您的情况下,请尝试以下方法:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy(); }, 1000);
}
if (this.options.destroyOnHide) {
setTimeout(this.tip.destroy.bind(this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}
同样的功能也被使用过(任何其他库?)
如果您想要自定义向后兼容性(但请遵守注释)
如果您已经在使用jQuery1.4+,那么有一个现成的函数可以显式设置函数的this
上下文
:获取一个函数并返回一个始终具有特定上下文的新函数
在您的情况下,请尝试以下方法:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy(); }, 1000);
}
if (this.options.destroyOnHide) {
setTimeout(this.tip.destroy.bind(this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}
,
它可以在underline.js和lodash中找到,如..bind(…)
将函数绑定到对象,这意味着每当调用函数时,this
的值都将是对象。(可选)将参数绑定到函数以预填充它们,也称为部分应用程序
在您的情况下,请尝试以下方法:
if (this.options.destroyOnHide) {
setTimeout(() => { this.tip.destroy(); }, 1000);
}
if (this.options.destroyOnHide) {
setTimeout(this.tip.destroy.bind(this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout($.proxy(this.tip.destroy, this.tip), 1000);
}
if (this.options.destroyOnHide) {
setTimeout(_.bind(this.tip.destroy, this.tip), 1000);
}
在Internet Explorer以外的浏览器中,您可以在延迟后将参数一起传递给函数:
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
因此,您可以这样做:
var timeoutID = window.setTimeout(function (self) {
console.log(self);
}, 500, this);
就性能而言,这比范围查找(将This
缓存到超时/间隔表达式之外的变量中),然后创建闭包(通过使用$.proxy
或Function.prototype.bind
)要好
使其在IEs中工作的代码来自:
如果正在使用,则可以使用bind
例如
注意:这在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);
它起作用了。我用一个jsbin脚本测试了这个概念:这段代码涉及到生成一个不必要的变量(具有函数范围);如果您正确地将this
传递给函数,那么对于这种情况,对于map()、forEach()等,您就可以使用更少的代码、更少的CPU周期和更少的内存来解决这个问题***参见:Misha Reyzlin的答案。为什么不默认函数绑定(上下文…
?我错过了什么吗?每次调用这个函数时,不断地创建一个新函数(bind就是这么做的)是否有效果?我有一个搜索超时,每次按键后都会重置,似乎我应该将这个“绑定”方法缓存到某个地方以供重用。@Triynko:我不认为绑定函数是一个昂贵的操作,但如果多次调用同一个绑定函数,您最好保留一个引用:var boundFn=fn.bind(此);boundFn();boundFn()例如,当使用原型链创建类时,您的方法是原型方法…'bind是唯一能改变方法中this的东西。通过向回调传递参数,您不会改变函数中的“this”是什么,因此不能像任何其他原型方法那样在函数中使用“this”编写这样的原型函数。这导致了不一致。绑定是最接近我们实际需要的东西,并且可以将闭包缓存在“this”中以获得更高的查找性能,并且不必多次创建它。复制标志真的有效吗?这个问题实际上是在前面问过的。if(This.options.destroonhide){setTimeout(function(){This.tip.destroy()}.bind(This),1000);}