Javascript 为什么可以';“我通过了”;窗口。位置。重新加载“;作为setTimeout的参数?

Javascript 为什么可以';“我通过了”;窗口。位置。重新加载“;作为setTimeout的参数?,javascript,cross-browser,Javascript,Cross Browser,我希望通过以下代码行了解我在Safari和Chrome中看到的错误: setTimeout(window.location.reload,250) Chrome报告: 未捕获类型错误:非法调用 和狩猎: TypeError:Type error 在FireFox中,代码运行良好。此外,此代码在三种浏览器中都可以正常运行: setTimeout((function() { window.location.reload(); }), 250); Chrome和Safari对此代码没有问题: v

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

setTimeout(window.location.reload,250)

Chrome报告:
未捕获类型错误:非法调用

和狩猎:
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
有什么特殊之处

(不确定它是否有用,但这里有一个示例)

因为
reload()
需要
窗口。位置
相同。换句话说,它是一种
window.location
方法。当你说:

var fun = window.location.reload;

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

这应该起作用:

setTimeout(window.location.reload.bind(window.location), 250);
window.location.reload.bind(window.location)
部分的意思是:获取
window.location.reload
函数并返回一个函数,当调用该函数时,该函数将使用
window.location
作为
引用

另见

因为当您调用
重新加载
时,此
必须绑定到
位置
。这与尝试相同:

var reload = window.location.reload;
reload();
在非严格模式下为
窗口
,在严格模式下为
未定义
,两者均无效

在非旧浏览器中,您可以执行以下操作:

reload.call(位置)

或者在你的例子中:

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

不过,较旧的IEs不支持主机对象上的显式绑定

对于某些非泛型的本机方法,您也会遇到这种情况,例如:

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"

这会失败,因为在传递时缺少
位置
上下文(函数的
This
)。 您必须
绑定
上下文,然后才能像这样使用它,例如与


这与通常从包含对象的控制台调用的任何其他函数一样。log

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

setTimeout(()=>window.location.reload(),250);

我不建议为本机已经存在的函数引入整个库。@jbabey如果您假设浏览器支持JavaScript 1.8.5(其中引入了
bind
),那么您是对的。为了向后兼容,我坚持使用underline.js,或者如果有人喜欢,可以(可能应该)使用Prototype.apply或call来代替bind
apply
,而
call
会立即执行
reload
函数,我怀疑goggin13想要什么;)如果您使用的是匿名函数,则无需使用
apply
call
,只需使用
window.location.reload()
即可。很高兴知道。猜猜为什么它能在Firefox中工作?@goggin13:很有趣。。。不确定。但这肯定不是便携式的。对,只是好奇而已。感谢
.bind
的解释,非常有用!
var boundReload = _.bind(window.location.reload, window.location);
setTimeout(boundReload, 500)