2

Let's have the following html:

<input id="txt" type="text" />

Now, in javascript, I can access its value by these following methods.

  1. var value = txt.value;

  2. var value = document.getElementById('txt').value;

So, is there any difference between them?

Amit Joki
  • 58,320
  • 7
  • 77
  • 95
  • Related: http://stackoverflow.com/questions/6381425/should-the-id-of-elements-be-made-global-variables-and, incidentally I'd prefer **2**, since defined behaviour is less likely to break in the future. – David Thomas Mar 30 '14 at 11:37

1 Answers1

6

First, consider what happens when someone look at the code written like this:

var value = txt.value;

There's exactly ZERO hint here that txt is actually 1) a global variable; 2) a DOM Element. Unless one scans the whole scope of a function (that means the function itself, the parent function it's defined in, its own parent etc. ... right till the outmost - global - scope). That means to understand the code, one has to check its whereabouts. Apparently that doesn't make the code nice to work with.

To illustrate this, consider what happens here:

function someAsyncFunc() {
  var txt = 'someText';
  // some lines of code
  someAsyncAction(function() {
    var value = txt.value;   
  });  
}

Here we have a function used as a callback in some asynchronous action. Technically, it doesn't have txt as a local variable to this specific function - but reference to a global variable is still shadowed by txt defined in its parent. The point is, it's way too easy to introduce subtle - yet very nasty - bugs by this potential clash of names.


That's for theory and reasoning, now about cross-platform practice. The whole idea of injecting the DOM Elements into the global scope (by making namespace resolver scan both window and document) for many years was considered, well, a bad idea - a shortcut that'll save you a couple of keystrokes when you write the code, but will more than compensate when someone (or you 6 months after) will debug the code. That's why, I suppose, Gecko engine didn't make such an injection in the standards mode - only in quirks.

Still, this idea has made its way in HTML5 Standard:

*Named objects [...] are those that are either:

  • a, applet, area, embed, form, frameset, img, or object elements that have a name content attribute whose value is name, or
  • HTML elements that have an id content attribute whose value is name.

There was a lengthy discussion about the correctness of such approach - which ultimately resulted in the approach staying as is. And the key reason was given by MS reps:

Our data suggests that making this quirks only would break a large number of web sites.

Yes, yet another victory for the bad practice used so often that it became a common practice. That's why Firefox 14+ supports this 'feature' as well. Still, the mere support of it doesn't make it right.

raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • `Firefox doesn't normally support injecting DOM Elements into a global scope by their IDs` what does this mean, can you please explore more about this? – Suman Bogati Mar 30 '14 at 12:00
  • Yes, since Firefox 14. I'll rewrite this answer massively, including links to HTML5 and discussion in Firefox changelogs. ) – raina77ow Mar 30 '14 at 12:04