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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10839989/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:10:29  来源:igfitidea点击:

Why can't I pass "window.location.reload" as an argument to setTimeout?

javascriptcross-browser

提问by goggin13

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 报告:
Uncaught TypeError: Illegal invocation

And Safari:
TypeError: Type error

和 Safari:
TypeError: Type error

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.reloadthat causes this error?

window.location.reload导致此错误的特殊之处是什么?

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

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

回答by Tomasz Nurkiewicz

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

因为reload()需要window.location作为this. 换句话说 - 它是window.location. 当你说:

var fun = window.location. reload;

fun();

You are calling reload()function without any thisreference (or with implicit windowreference).

您在reload()没有任何this引用(或隐式window引用)的情况下调用函数。

This should work:

这应该有效:

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

The window.location.reload.bind(window.location)part means: take window.location.reloadfunction and return a function that, when called, will use window.locationas thisreference inside reload().

window.location.reload.bind(window.location)部分意味着:获取window.location.reload函数并返回一个函数,该函数在调用时将window.location用作this内部的引用reload()

See also

也可以看看

回答by Esailija

Because thismust be bound to locationwhen you call reload. It's same as trying:

因为调用的时候this一定要绑定。这与尝试相同:locationreload

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

thiswould be windowin non-strict mode and undefinedin strict mode which are both invalid.

thiswindow处于非严格模式和undefined严格模式,这两者都是无效的。

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"

回答by Tharabas

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

这会失败,因为在以您的方式传递location上下文this时,您缺少上下文(函数的)。您必须先bind了解上下文,然后才能像这样使用它,例如使用underscore.js bind 方法

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