为什么我无法通过“[removed].reload”作为参数传递给setTimeout的?(Why

2019-06-25 00:57发布

我喜欢的一些见解,我在Safari和Chrome上看到与下面的代码行的错误:

setTimeout(window.location.reload, 250);

Chrome的报道:
Uncaught TypeError: Illegal invocation

和Safari:
TypeError: Type error

在Firefox中,代码运行正常。 此外,该代码运行在三个浏览器的罚款:

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

Chrome和Safari浏览器有这个代码没有任何问题:

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

有什么特别之处window.location.reload导致这个错误?

(不知道它的有用与否,但这里有一个的jsfiddle说明这一点)

Answer 1:

因为reload()需要window.locationthis 。 换言之-它是一个方法window.location 。 当你说:

var fun = window.location. reload;

fun();

要调用reload()没有任何功能this引用(或隐含window参考)。

这应该工作:

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

所述window.location.reload.bind(window.location)部分是指:取window.location.reload功能并返回,调用它时,将使用一个函数window.location作为this内部参考reload()

也可以看看

  • 如何传递的参数时使用的setTimeout调用的函数?
  • 当作为参数传递的forEach为什么不CONSOLE.LOG工作?
  • 保留在JavaScript中的原型事件处理“这个”参考


Answer 2:

因为this必须绑定到location ,当你调用reload 。 这是一样的尝试:

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

this将是window在非严格模式和undefined严格模式,都是无效的。

在非旧的浏览器,你可以做,而不是:

reload.call( location )

或在您的例子:

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

年长的IE不支持明确,虽然在主机的对象结合。

您还可以得到这是在不通用的,如一些本地方法:

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

有些是通用的:

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


Answer 3:

这将失败,因为你错过了location上下文(函数的this ),路过的时候它自己的方式。 你将不得不bind的情况下,才可以用这样使用它,例如underscore.js绑定方法

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

这是一个与其他功能通常是由叫是一个包含类似对象相同console.log



文章来源: Why can't I pass “window.location.reload” as an argument to setTimeout?