我希望通过以下代码行了解我在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说明了这一点)
答案 0 :(得分:62)
因为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()
引用。< / p>
答案 1 :(得分:3)
当您致电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"
答案 2 :(得分:2)
这会失败,因为您错过了location
上下文(函数的this
),当您按自己的方式传递时。
您必须bind
上下文,然后才能像这样使用它,例如使用underscore.js bind method
var boundReload = _.bind(window.location.reload, window.location);
setTimeout(boundReload, 500)
与通常从其中包含console.log
答案 3 :(得分:2)
还有另一种方法可以做到这一点,非常简单,无需执行额外的步骤,绑定或类似的操作。当您使用箭头函数代替JS中的常用函数时,将包含this
上下文。因此,您可以轻松地执行以下操作:
setTimeout(() => window.location.reload(), 250);