35

I've noticed that calls like setTimeout() work either as :

self.keyword()

or just on their own e.g. keyword().

What is the different between the two calls?

Konrad
  • 39,751
  • 32
  • 78
  • 114
  • Check this http://stackoverflow.com/questions/3216428/self-keyword-in-javascript – PSK Jul 22 '10 at 13:51

3 Answers3

33

self can refer to the window object, but typically that's not the case here. You'll see this commonly above that setTimeout():

var self = this;

They're keeping a reference to the current object, so later when you call self.keyword() you're calling that method on that object, not any other.

Say you have for example images in the page you wanted to rotate every 2 seconds...you'd want each of those 3 timers to refer to their own methods. If they use this directly, it would (most of the time) refer to window and not the current object, whereas passing another variable in maintains the current reference.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • But a method like setTimeout is global and provided by the JVM rather than an object? – Konrad Jul 22 '10 at 13:55
  • 1
    @Konrad - `setTimeout()` is a global function itself, but it can execute any function, for example: `setTimeout(myFunction, 1000);` or `setTimeout(function() { alert(this); }, 1000);` – Nick Craver Jul 22 '10 at 13:57
14

It works with setTimeout because of two conditions in the browser:

  • All global variables are properties of the window object. That means that window has a property setTimeout (window.setTimeout).
  • The window object has a property called self that points to itself.

As you can access the properties of window without explicitly writing window (that is what makes the global variables global), both calls work: setTimeout() will look up the property setTimeout() on the window object. self.setTimeout() will look up the property self on the window object, which is the window object itself.

So if you call self.setTimeout() it is the same as window.self.setTimeout() which is the same as window.setTimeout() which again is the same as setTimeout().

Note: This only works if there is no variable self defined in the current scope that shadows the global self.

This works with any symbol (meaning variable or function) defined in the global scope. You can test it yourself:

alert(window.self);

and

alert(self);

should both alert

[object Window]
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 1
    Re your first point, it's really the other way round: `setTimeout` is a method of the `window` object that happens to be appear to be global because `window` points to the global object. – Tim Down Jul 22 '10 at 15:56
  • @Tim Down: Thank you for clarification. I always get a bit confused when it is about global and window object ;) – Felix Kling Jul 22 '10 at 16:03
8

Every property and method on window object can be called with or without 'window.'.

and

self is a read-only property on window object that returns the window itself (MDN)

so

setTimeout()

window.setTimeout()

window.self.setTimeout()

self.setTimeout()

are all same thing.

The main advantage of doing self.setTimeout() instead of window.setTimeout() or any other way is that, if you run some code that calls window.setTimeout() inside WebWorker, it will fail but the self.setTimeout() will work both in web workers and the browser context. So if you are writing a library that should work both on main window's scope and the web worker, we should prefer using self.

self always refer to the GlobalScope which in case of browser mode is window and inside web workers is `WorkerGlobalScope'

Hitesh.Aneja
  • 3,523
  • 3
  • 18
  • 14