Self-referential global object: what is it for and why does it exist?

Asked

Viewed 454 times

22

The object window in browsers has a property window that is self-reference:

window.window === window; // true

And there are other similar properties in browsers:

self === window; // true
top === window;  // true
self === top;    // true
self.top.window === window.top.self; // true

In Node.js, the global object is also self-referential:

global.global === global; // true

What is the usefulness of these properties, and what is the reason for their existence?

2 answers

12


The necessity of property window.window comes from the way Javascript references its variables. Every time an expression is created involving a identifier (i.e. a name) to engine do JS searches on a special object - called Variable Object - by the key corresponding to that identifier. (this object is probably named for its function: an object that stores variables)

console.log(x + 1); // Procura por <<Variable Object>>['x'] 
                    // e depois por <<Variable Object>>['console']

When the code to be executed is in top-level, Variable Object is equivalent to Global Object (that, in the browser, would be the window, but in other environments may be different). Ie:

console.log(x + 1); // Procura por window['x'] 
                    // e depois por window['console']

When this code is inside a function, Variable Object is called Activation Object, and is different for each function invocation:

function foo() {
    console.log(x + 1);
}

foo(); // Procura por <<Activation Object 1>>['x'] 
       // e depois por <<Activation Object 1>>['console']
foo(); // Procura por <<Activation Object 2>>['x'] 
       // e depois por <<Activation Object 2>>['console']

The programmer does not have direct access to the Activation Object, only indirectly through the attempt to access a property by name. An Activation Object defines a execution context, that is, a set of variables that are accessible to be used by that code snippet. An execution context can "inherit" from another context, which it can inherit from another, and so on (for more details, see that my other answer in the question "How closures work in javascript?"). Example:

function foo() {
    var x;
    function bar() {
        console.log(x + 1);
    }
    bar();
}
foo(); // Procura por <<Activation Object "bar" 1>>['x']
       //         ... <<Activation Object "foo' 1>>['x'] (encontrou)
       // e depois por <<Activation Object "bar" 1>>['console']
       //          ... <<Activation Object "foo" 1>>['console']
       //          ... window['console'] (encontrou)

Well, in possession of this explanation, I ask: what happens when we simply write:

window

// ou

function foo() {
    window
}
foo();

? The Javascript engine will do what it always does when it finds an identifier: search in Variable Object:

window   // Procura por window['window']

function foo() {
    window
}
foo();   // Procura por <<Activation Object "foo" 1>>['window']
         //         ... window['window'] (encontrou)

That is: so that the programmer can access the Global Object (window), he needs to have a reference to himself (window['window'] or simply window.window). The same goes for Node.js (global.global) and for any other Javascript implementation that exposes the global object to programmers (whether this is mandatory or not according to the Ecmascript specification, I have not checked).

The variable self (global) also refers to the object window, in accordance with the specification of W3.org. What about top, she may or may not refer to window, as explained by @Hernandes.

Source: most of this response was based on the article (in English) "Understanding delete".

  • +1 because I think it answers the question better, but I would +10 for the link to "Understanding delete". There are some points in the answer that I found a little confusing, but I can’t say anything because most of the time I’m a confused person. Anyway, it is very worth reading this article in English.

  • 2

    Excellent! Just one detail: this kangax article (all of it great, right?) is a little outdated, uses the terminology of Ecmascript 3. In ES5, variable Object and Activation Object are now treated as declarative Environment Records.

4

self is set in the Javascript environment and points to the objeto global, but is not part of the specification of DOM, and may not be present in the browser. While window is part of the specification of DOM. In most browsers, window is used as objeto global but this may vary.

self == window.self is not a strange thing, for they are actually the same object (how much self is used, is found to be a property of the global object (window)), so that’s the same as using window.self == window.self.

To have a reference concise of the global object, you must define on your own as follows (when you are in the global context):

var global = this;

So you see, top (window.top) is used to reference the object window higher, for example, if you have several nested frames, window.top will reference the main page and not the frames, top is used to tell whether or not you are inside a frame:

if(window.top != window.self) {
    alert("Estamos em um frame");
} 

The Reason We Have window.window (property window of the object window) is to facilitate referencing the objeto global, calling only window within frame, we are referencing the frame, window.window we are referencing the global object, regardless of where

  • Right, self == window.self might not be weird, but and window.window == window?

  • I’ll edit the answer

  • I answered after < hr >

  • Where do you learn to do that? Advanced books?

  • 3

    @Joaopaulo I don’t know how Hernandes learned, but usually this kind of thing you get with a mix of experience, research in documentations, forums like this, articles and books, and a lot of curiosity. There will hardly be a definitive source on any matter of technology.

  • 1

    @utluiz exactly, and the Internet has much more content than any advanced book.

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.