What do the keywords "self" and "window" represent in JavaScript?
2022 Update - I added this explanation below with more complete information affecting HTML5 DOM, etc. in modern browsers.
- For starters,
self
and window
are just keywords, and are names of members in the Window Object interface. They are keywords that reference the same window object that gets created when you visit a web page in the browser. A Window Object then gets created as part of the HTML DOM accessed by scripts like JavaScript with these two keywords assigned. This Window Object is then commonly accessed via the more popular window
keyword. However, the two keywords are allowed as defined in the interface definition shown below:
interface Window {
readonly attribute WindowProxy window;
readonly attribute WindowProxy self;
...
}
self
and window
are just JavaScript keywords that point to the same Window Object. However, notice above they do not point back to the parent itself, but are actually pointers to a WindowProxy object. The WindowProxy Object is a wrapper around the Window Object shown above, and exists in one instance for every web page Window you visit in the web browser context. Note that only one WindowProxy Object exists per tab. However, as you surf to different web pages, a new Window Object must be created inside the mother WindowProxy. This allows the browser to manage all Window Objects it creates via its proxy object without having to lose each window browsing context and view. The WindowProxy is both a security and memory feature, allowing access to each underlying window instance each page view creates, while protecting the wrapped Window Object child inside it.
When the window gets created, assigning self
and window
keywords to its proxy allows both to access the parent proxy instead of a specific Window Object instance, and let the WindowProxy route any calls to the current window context.
Besides security and context of referencing the WindowProxy, this routing to the Window Object via a wrapper was especially important in the old "frame" HTML days when there might be many window contexts holding other parent or child window object in HTML4 frames. This was especially important in cross-domain issues in frames 20 years ago! That is the next reason for self
vs window
. The keyword self
(as in window.self
) used to have another important meaning, and was actually used to help determine what frame you were referencing. It was used to represent a specific window context and reference the top or controlling web page frame that held other frames. window.self
might or might not be the same as window.parent.frame[0]
, for example! Those "frame days" are basically dead due to security issues accessing windows in frames, so were deprecated after HTML4.2 was replaced with HTML5, which only supports the iframe
now. However, its important to realize self
had a prior use beyond its primary reference back to the global scope of a web page's top Window Object, as used today.
Next, notice that the following is true in JavaScript when inside a typical window or web page browsing context:
self === window.self === window
So why use self
today if you have window
?
It turns out that window
, like self
, always points to the WindowProxy object, which then points back again to the window itself again and the current Window Object instance in the browser tab. It's self-referential
, yet can ONLY point to itself.
But self
, when used inside other non-window contexts, can refer to its global scope or parent, including Web Worker API Objects, which are parallel threads that run alongside the Window Object and which have their own non-window scope. When you create a Web Worker object in JavaScript, and use self to access it, you are referencing the top object of the Web Worker called WorkerGlobalScope
. However, self can also reference different flavors of the Web Worker global scope when they are other types like DedicatedWorkerGlobalScope
, ServiceWorkerGlobalScope
, etc. These all exist OUTSIDE the Window Object, and have their own global scope like window
.
So self
now has a larger purpose as an alias to whatever Global Scope
or parent object is being accessed!
No one online seems to explain any of this...so I had to patch together this concept from lots of references. But the overall theme is that these keywords in JavaScript don't always self-reference the same objects! Each was added to overlap each other (and thus confuse people), but then supersede their primary purpose and be used for extended purposes that might appear.
So if you see self
and window
, understand in a typical window global scope, they are the same. These key words are both designed to reference the Window Object via the WindowProxy wrapper quickly and securely. But I recommend you ALWAYS use window
and avoid self
, unless you are dealing with Web Workers.