What's the difference between self and window?
I have a JavaScript that deals with with detection whether the page is in frames or not. I used top.frames[] etc. and everything works fine.
In this script I noticed that I can use "window" or "self" interchangeably and everything still works. Is "window" same as "self开发者_开发技巧" when used in HTML page?
self
is a read-only property that can be more flexible than, and sometimes used in favor of, the window
directly. This is because self
's reference changes depending on the operating context (unlike window.self
, which only exists if window
exists). It's also great for comparisons, as others have mentioned.
For example, if you use self
inside a Web Worker (which lives in its own background thread), self
will actually reference WorkerGlobalScope.self
. However, if you use self
in a normal browser context, self
will simply return a reference to Window.self
(the one that has document
, addEventListener()
, and all the other stuff you're used to seeing).
TL;DR while the .self
in window.self
will not exist if window
doesn't exist, using self
on its own will point to Window.self
in a traditional window/browser context, or WorkerGlobalScope.self
in a web worker context.
As usual, MDN has a great writeup on this subject in their JavaScript docs. :)
Side note: The usage of self
here should not be confused with the common JS pattern of declaring a local variable: var self = this
to maintain a reference to a context after switching.
You can read more about that here: Getting Out of Binding Situations in JavaScript.
From Javascript: The Definitive Guide:
The Window object defines a number of properties and methods that allow you to manipulate the web browser window. It also defines properties that refer to other important objects, such as the
document
property for the Document object. Finally, the Window object has two self-referential properties,window
andself
. You can use either global variable to refer directly to the Window object.
In short, both window
and self
are references to the Window object, which is the global object of client-side javascript.
Here's the explanation and example from the MDN page for window.self
:
if (window.parent.frames[0] != window.self) {
// this window is not the first frame in the list
}
window.self is almost always used in comparisons like in the example above, which finds out if the current window is the first subframe in the parent frameset.
Given that nobody is using framesets these days, I think it's okay to consider that there are no useful cases for self
. Also, at least in Firefox, testing against window
instead of window.self
is equivalent.
window
and self
both refer to the global object of the current web page.
For more info have a look at http://www.howtocreate.co.uk/tutorials/javascript/browserinspecific
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
andwindow
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 popularwindow
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
andwindow
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, assigningself
andwindow
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
vswindow
. The keywordself
(as inwindow.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 aswindow.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 theiframe
now. However, its important to realizeself
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.
精彩评论