Почему я не могу передать «window.location.reload» в качестве аргумента setTimeout?

Мне бы хотелось немного разобраться в ошибке, которую я вижу в Safari и Chrome со следующей строкой кода:

setTimeout(window.location.reload, 250);

Отчеты Chrome:
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 иллюстрирую это)

Ответы на вопрос(3)

Решение Вопроса

Так как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().

See also

Так как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"

Это не удается, потому что вы упускаетеlocation контекст (функцияthis), при прохождении вашего пути. Вы должны были быbind контекст, прежде чем вы можете использовать его, например, сметод связывания underscore.js

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

То же самое с любой другой функцией, которая обычно вызывается из содержащего ее объекта, напримерconsole.log

Ваш ответ на вопрос