The standard
The HTML5 standard specifies that the window object must have a property key whose value is elem if...- there is exactly one DOM element elem whose property id has the value key.
- there is exactly one DOM element elem whose property name has the value key. elem’s tag must be one of: a, applet, area, embed, form, frame, frameset, iframe, img, object.
<div id="foo"></div>
Thus, the div element above can be accessed either via window.foo or, like all properties of window, via the global variable foo. For example, in the Chrome console, you can do the following:
> "foo" in window
true
> foo
<div id="foo"></div>
Firefox
Firefox (version 14) works slightly differently.
> "foo" in window
false
> typeof foo // does the variable exist?
object
Element referenced by ID/NAME in the global scope.
Use W3C standard document.getElementById() instead.
> foo
[object HTMLDivElement]
Element referenced by ID/NAME in the global scope.
Use W3C standard document.getElementById() instead.
> "foo" in window
true
What does that mean? Initially, there is no property window.foo. But the first time it is accessed (either directly or via the global variable foo), it is created automatically.
[Note: the code above can only be executed via a script tag, but not via the console. That is because the console handles global variables differently, so that the auto-creation process doesn’t work properly.]
Whenever you read foo, the div element is returned and a warning tells you not to do that. Obviously, the warning is correct: It’s fine to use this feature interactively, but you should not rely on it in actual code.
Updates
Update 1: Cody Lindley has written a jsPerf test comparing the performance of accessing foo via a global variable versus via window.foo. Interestingly, Firefox is the only browser where window.foo is faster.Update 2: Commenter tjvantoll mentions where HTML5 standardizes that element IDs become properties of window. In reaction to that, the post now describes what is specified there.
6 comments:
This "feature" first bit me in my ass around 2006. I believe I was figuring out a bug in one of my scripts. Turned out I had forgotten a "var" somewhere. At the time I drew a relation to PHP's register_globals (making any input a variable) - and concluded this JS behavior being the same kind of "making things easy" bullshit that ultimately can lead to only one thing: bad code.
I have not seen anyone actually using this "feature" in quite a while. I truly hope - spite the fuss made on twitter et al - it stays that way.
I agree, more a bug than a feature.
But it shows that people like the JavaScript dev tools. And that convenience features are welcome.
An example (that is possibly mainly useful for teaching): The Khan Academy JavaScript course [1] has a great code editor – you can use a slider to change numeric arguments. While doing so, shapes move around (etc.) on screen.
[1] http://www.khanacademy.org/cs
This "feature" actually works in IE's dev tools, Opera dragonfly, and Safari's web inspector as well. That's because it's actually part of the HTML5 specification - http://www.whatwg.org/specs/web-apps/current-work/#named-access-on-the-window-object.
I wrote about this behavior awhile ago after it bit me in a production application - http://tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/.
If you like that slider thingie, watch http://vimeo.com/36579366 -
I'm pretty sure that's where KhanAcademy got the idea from. It is, at the very least, where I saw this first.
I don't, however, understand your jump from code to UI. Within the dev tools, "auto-global-elemIDs" are just as useful as "$0" (reference to the currently selected element in the DOM tab). I never doubted that. Just don't ever put it into production code.
“I don't, however, understand your jump from code to UI.”
Freely associated, because I really like what they have done (including the spunky narrator). Common thread: Little helpers for REPLs.
I remember reading about this in "Javascript: The Definitive Guide":
http://books.google.com/books?id=4RChxt67lvwC&pg=PA352&lpg=PA352&dq=javascript+the+definitive+guide+id+global&source=bl&ots=tgZ6zjOVpa&sig=fMYiqLUK4H5x7s1BsEh7Ef-eAZc&hl=en&sa=X&ei=JtQrUMRx5bfqAYK2gRg&ved=0CFoQ6AEwBQ#v=onepage&q=javascript%20the%20definitive%20guide%20id%20global&f=false
While it's surely a feature that carries more risk than most, it seems to be part of the canon and a real, universally implemented feature. It's odd that Firefox would choose this particular feature (among javascript's many awkard/inconsistently imlpemented ones) to warn you about.
I wonder if it warns you if you use any of Firefox's nonstandard Javascript extensions too :)
Post a Comment