为什么我不能将“window.location.reload”作为参数传递给setTimeout?

时间:2022-07-06 17:07:40

I would love some insight into the error I am seeing in Safari and Chrome with the following line of code:

我希望通过以下代码行深入了解我在Safari和Chrome中看到的错误:

setTimeout(window.location.reload, 250);

setTimeout(window.location.reload,250);

Chrome reports:
Uncaught TypeError: Illegal invocation

Chrome报告:未捕获TypeError:非法调用

And Safari:
TypeError: Type error

和Safari:TypeError:输入错误

In FireFox, the code runs fine. Also, this code runs fine in each of the three browsers:

在FireFox中,代码运行正常。此外,此代码在三个浏览器中的每个浏览器中运行良好:

setTimeout((function() {
  window.location.reload();
}), 250);

Chrome and Safari have no issues with this code:

Chrome和Safari对此代码没有任何问题:

var say_hello = function () { alert("hello") };  
setTimeout(say_hello, 250);  

What is special about window.location.reload that causes this error?

有关导致此错误的window.location.reload有什么特别之处?

(not sure if it's useful or not, but here's a jsfiddle illustrating this)

(不确定它是否有用,但这里有一个说明这个的jsfiddle)

3 个解决方案

#1


55  

Because reload() needs window.location as this. In other words - it is a method of window.location. When you say:

因为reload()需要window.location。换句话说 - 它是window.location的一种方法。当你说:

var fun = window.location. reload;

fun();

You are calling reload() function without any this reference (or with implicit window reference).

您正在调用reload()函数而不使用任何此引用(或使用隐式窗口引用)。

This should work:

这应该工作:

setTimeout(window.location.reload.bind(window.location), 250);

The window.location.reload.bind(window.location) part means: take window.location.reload function and return a function that, when called, will use window.location as this reference inside reload().

window.location.reload.bind(window.location)部分表示:获取window.location.reload函数并返回一个函数,该函数在调用时将使用window.location作为reload()内的引用。

See also

#2


3  

Because this must be bound to location when you call reload. It's same as trying:

因为在调用reload时必须将其绑定到位置。它和尝试一样:

var reload = window.location.reload;
reload();

this would be window in non-strict mode and undefined in strict mode which are both invalid.

这将是非严格模式下的窗口,严格模式下未定义,这两者都是无效的。

in non-old browsers you can do instead:

在非旧版浏览器中,您可以改为:

reload.call( location )

reload.call(location)

or in your example:

或者在你的例子中:

setTimeout( window.location.reload.bind( window.location ), 1000 )

setTimeout(window.location.reload.bind(window.location),1000)

Older IEs don't support explicit binding on host objects though.

但较旧的IE不支持对主机对象进行显式绑定。

You also get this for some native methods which are not generic such as:

您还可以获得一些非通用的本机方法,例如:

var a = function(){}.toString;
a();
TypeError: Function.prototype.toString is not generic

Some are generic:

有些是通用的:

var fakeArray = {0:1,1:2,length:2};
fakeArray.join = [].join;
fakeArray.join( " " );
"1 2"

#3


2  

This fails because you're missing the location context (the function's this), when passing it your way. You would have to bind the context, before you can use it like this, for example with the underscore.js bind method

这失败是因为你错过了位置上下文(函数是这个),当你按自己的方式传递时。您必须先绑定上下文,然后才能像这样使用它,例如使用underscore.js绑定方法

var boundReload = _.bind(window.location.reload, window.location);
setTimeout(boundReload, 500)

It's the same with any other function that is usually called from it's containing object like console.log

它与通常从包含console.log之类的对象调用的任何其他函数相同

#1


55  

Because reload() needs window.location as this. In other words - it is a method of window.location. When you say:

因为reload()需要window.location。换句话说 - 它是window.location的一种方法。当你说:

var fun = window.location. reload;

fun();

You are calling reload() function without any this reference (or with implicit window reference).

您正在调用reload()函数而不使用任何此引用(或使用隐式窗口引用)。

This should work:

这应该工作:

setTimeout(window.location.reload.bind(window.location), 250);

The window.location.reload.bind(window.location) part means: take window.location.reload function and return a function that, when called, will use window.location as this reference inside reload().

window.location.reload.bind(window.location)部分表示:获取window.location.reload函数并返回一个函数,该函数在调用时将使用window.location作为reload()内的引用。

See also

#2


3  

Because this must be bound to location when you call reload. It's same as trying:

因为在调用reload时必须将其绑定到位置。它和尝试一样:

var reload = window.location.reload;
reload();

this would be window in non-strict mode and undefined in strict mode which are both invalid.

这将是非严格模式下的窗口,严格模式下未定义,这两者都是无效的。

in non-old browsers you can do instead:

在非旧版浏览器中,您可以改为:

reload.call( location )

reload.call(location)

or in your example:

或者在你的例子中:

setTimeout( window.location.reload.bind( window.location ), 1000 )

setTimeout(window.location.reload.bind(window.location),1000)

Older IEs don't support explicit binding on host objects though.

但较旧的IE不支持对主机对象进行显式绑定。

You also get this for some native methods which are not generic such as:

您还可以获得一些非通用的本机方法,例如:

var a = function(){}.toString;
a();
TypeError: Function.prototype.toString is not generic

Some are generic:

有些是通用的:

var fakeArray = {0:1,1:2,length:2};
fakeArray.join = [].join;
fakeArray.join( " " );
"1 2"

#3


2  

This fails because you're missing the location context (the function's this), when passing it your way. You would have to bind the context, before you can use it like this, for example with the underscore.js bind method

这失败是因为你错过了位置上下文(函数是这个),当你按自己的方式传递时。您必须先绑定上下文,然后才能像这样使用它,例如使用underscore.js绑定方法

var boundReload = _.bind(window.location.reload, window.location);
setTimeout(boundReload, 500)

It's the same with any other function that is usually called from it's containing object like console.log

它与通常从包含console.log之类的对象调用的任何其他函数相同