Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does setTimeout(location.reload) throw a TypeError? [duplicate]

I'm trying to understand the strange behavior of this code:

window.setTimeout(window.location.reload, 200);
  • In Firefox this throws a TypeError:

    TypeError: 'reload' called on an object that does not implement interface Location.

  • In Chromium this throws another TypeError:

    Uncaught TypeError: Illegal invocation


These two alternatives work fine:

  • window.setTimeout('window.location.reload()', 200);
  • window.setTimeout(function(){window.location.reload()}, 200)

Why?

like image 294
Sjon Avatar asked Sep 09 '16 09:09

Sjon


People also ask

Why does setTimeout return undefined?

If you are calling it from the console then 'undefined' is correct behaviour, since the function call produces no return object. setTimeout returns a timeout ID, which can be used to clear the timeout. Are you trying to find out how many milliseconds the setTimeout has left?

Is setTimeout guaranteed?

setTimeout is a guarantee to a minimum time of execution.

Does setTimeout block execution?

Explanation: setTimeout() is non-blocking which means it will run when the statements outside of it have executed and then after one second it will execute.

Does setTimeout return value?

The setTimeout() returns a timeoutID which is a positive integer identifying the timer created as a result of calling the method. The timeoutID can be used to cancel timeout by passing it to the clearTimeout() method.


1 Answers

This is due to the fact that window.location.reload will be called out of context, so the actual function reload() does not have any reference to the location object.

In JavaScript, if you call a function foo.bar(), the context is foo, so this refers to foo within the function bar.

However, if you assign var a = foo.bar and then call a() (which is still the same function), it will have no context, so this will be undefined. This is what happens when you pass the function as a method parameter.

The usual way to work around this issue is to bind the context:

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

This ensures that the function will always be called in the context of window.location, no matter how it is called.

There is a nice example in the Mozilla docs.

like image 164
Tobias Avatar answered Sep 28 '22 02:09

Tobias