51

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

setTimeout(window.location.reload, 250);

铬报告:
Uncaught TypeError: Illegal invocation

和野生动物园:
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说明了这一点)

4

4 回答 4

87

因为reload()需要window.location作为this. 换句话说 - 它是一种方法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()

也可以看看

于 2012-05-31T19:29:33.373 回答
4

还有另一种方法可以做到这一点,非常简单,不需要额外的步骤、绑定或类似的东西。当你在 JS 中使用箭头函数而不是常用函数时,this上下文是包括在内的。因此,您可以轻松地执行以下操作:

setTimeout(() => window.location.reload(), 250);
于 2020-09-24T06:51:04.787 回答
3

因为在调用时this必须绑定。这与尝试相同:locationreload

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

thiswindow处于非严格模式和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"
于 2012-05-31T19:31:14.080 回答
2

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

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

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

于 2012-05-31T19:33:12.097 回答