为什么必须在setTimeout中包装函数? [英] Why do I have to wrap functions in setTimeout?

查看:159
本文介绍了为什么必须在setTimeout中包装函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为什么要写

setTimeout(function() { $('#selector').focus() }, 100);

代替

setTimeout($('#selector').focus, 100);

后者在Firefox中为我提供了TypeError this.trigger is not a function,但显然它是一个函数,因为typeof $('#selector').focus是函数".这是怎么回事?

The latter gives me a TypeError this.trigger is not a function in Firefox, but clearly it is a function since typeof $('#selector').focus is "function." What's going on here?

推荐答案

这是由于this问题引起的.根据 MDN文档:

This is because of the this problem. Per MDN documentation:

setTimeout()执行的代码从单独的执行上下文调用到调用setTimeout的函数.设置被调用函数的this关键字的通常规则适用,如果您未在调用中或使用bind设置this,它将默认为非以下对象中的全局(或window)对象:严格模式,或者在严格模式下为undefined.与调用setTimeout的函数的this值不同.

Code executed by setTimeout() is called from a separate execution context to the function from which setTimeout was called. The usual rules for setting the this keyword for the called function apply, and if you have not set this in the call or with bind, it will default to the global (or window) object in non–strict mode, or be undefined in strict mode. It will not be the same as the this value for the function that called setTimeout.

在JavaScript中,有一个执行上下文"的概念,该上下文包含有关当前正在执行的内容的信息.有一个全局执行上下文,当调用一个函数时,会创建一个新的执行上下文.然后,this值取决于执行上下文,并根据当前执行上下文设置.由于setTimeout会在调用目标函数时创建新的执行上下文,因此this并不表示DOM中的jQuery对象,而是表示全局对象(默认情况下,或在严格模式下未定义).因此,当jQuery内部调用this.trigger时,它将尝试调用不存在的window.trigger.

In JavaScript, there's a concept of "execution contexts", which are contexts that hold information about what is currently executing. There's a global execution context, and when a function is called, a new execution context is created. The this value then depends on the execution context and is set according to the current execution context. Since setTimeout creates a new execution context when the target function is called, this does not represent the jQuery object from the DOM, but the global object (as it is by default, or undefined in strict mode). Thus when jQuery internally calls this.trigger it is trying to call window.trigger which does not exist.

尝试使用Function#bind显式设置this值:

setTimeout($('#selector').focus.bind($('#selector')), 100);

或者,正如瑞安(Ryan)所述:

Or, as Ryan mentions:

setTimeout($.fn.focus.bind($('#selector')), 100);

当然,您可以使用箭头功能,它比使用bind更快,并且更惯用:

Of course, you could, as squint mentioned, use an arrow function instead, which is faster than using bind and more idiomatic:

setTimeout(() => $('#selector').focus(), 100);

这篇关于为什么必须在setTimeout中包装函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆