7

This question ( Element accessible with ID ) points out that if an element has an id then you can access it by variable name based on that id. It intrigued me, as I had seen this variable available when developing using Visual Studio 2010. I did some testing out of curiosity and it turns out that document.getElementById() was still faster than using the variable name. So, I began trying to look through the window, figuring it must be in window["idName"], in debug, and with console.log(window) and could not find where the variable was actually stored.

When an element is defined in html with <div id="foo"> it is available in javascript with the variable foo (I am not suggesting to use this, it is bad practice). Where is that variable stored?

Community
  • 1
  • 1
Travis J
  • 81,153
  • 41
  • 202
  • 273
  • 1
    Please do not make it a practice to access elements as global variables. It's a hideous IE invention, and is non-standard. Exactly where the identifier is located is up to the implementation, since there's no standard to define this. – I Hate Lazy Oct 01 '12 at 19:58
  • @user1689607 - I agree that it is bad practice (even noted here in the question and in the linked one not to use it). – Travis J Oct 01 '12 at 20:00

1 Answers1

7

This is non-standard behavior. Where (and if) it is stored is up to the implementation.


Using Firefox 15 on Linux, I had to go 2 prototype objects deep to find the actual object. I ran this code on this StackOverflow page, and got a true result.

Object.getPrototypeOf(Object.getPrototypeOf(window)).hasOwnProperty("hlogo");

In Chrome on Linux, it was one level deep.

Object.getPrototypeOf(window).hasOwnProperty("hlogo");

I was actually surprised to see it in Firefox, but since Chrome followed the Microsoft pattern, I guess Firefox must have felt the need to follow suit.


If you don't know how deep a prototype chain is, you can run a loop, and add the different objects to an Array, or just work with the objects in the loop.

var protos = [],
    obj = window;

while (Object.getPrototypeOf(obj) !== null) {
    obj = Object.getPrototypeOf(obj);
    protos.push(obj);
}

alert("The object had " + protos.length + " prototype objects");
I Hate Lazy
  • 47,415
  • 13
  • 86
  • 77
  • 1
    And in Chrome, that's `false`, but `Object.getPrototypeOf(window).hasOwnProperty("hlogo")` is `true`. – Matt Ball Oct 01 '12 at 20:04
  • @MattBall: Yes, just tested that myself. Updated my answer. Thanks. – I Hate Lazy Oct 01 '12 at 20:05
  • 1
    @user1689607 - Very nice, thank you for showing a repeatable way to view this variable. I tested with Firefox and was able to get the result "two prototype objects deep". Do you think you could expand on why it took two, and what the outer `Object.getPrototypeOf` means here? – Travis J Oct 01 '12 at 20:09
  • 1
    @TravisJ: The `Object.getPrototypeOf` method is a way to retrieve the prototype object of an object. A prototype chain can be longer than just one object, so basically the Firefox code says *"give me the prototype object of the prototype object of the `window` object"*. In other words, the inner one gets the prototype of `window`, and so the outer gets the prototype of the prototype of `window`. – I Hate Lazy Oct 01 '12 at 20:12
  • @TravisJ: I'll update with a loop that will add each prototype object in the prototype chain to an Array. Index `0` will be closest to the original object. – I Hate Lazy Oct 01 '12 at 20:14
  • @user1689607 - Thanks for the extra explanations, I appreciate it. I understand prototypes, but do not yet have a strong grasp of them. – Travis J Oct 01 '12 at 20:16