0

I'm writing a script that I want to keep from polluting the rest of the DOM, it will be a 3rd party script to collect some basic visitor analytic data.

I usually create a pseudo "namespace" using something like: var x = x || {};

Some of the other peoples code I'm looking at uses: x = window.x || {};

I know that not setting var will set a global var. Is that the only difference?

I'm examining the two objects in Chrome and Webstrom and they look identical.

Can someone explain the difference between these two approached and the implications of using one over the other (if there is one)?

As I said, when I examine the objects that get created they look identical to me but I’ve learned with JS... appearances can be deceiving.

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Cyph
  • 623
  • 1
  • 7
  • 25
  • 1
    The second one doesn't seem to make sense to me. Could you point to an example online ? – Denys Séguret May 30 '14 at 16:48
  • If your code is going to be used with require.js / in node.js, you may also want to consider calling `define` or setting `module.exports` conditionally – urish May 30 '14 at 16:49
  • The first one works in strict mode, the second one does not because implicit globals are not allowed - they must be declared with `var`. – jfriend00 May 30 '14 at 16:55
  • I think this is mostly a question of readability. My preference is to take `window.x` over a `var x` that happens to be in the global space. If you convert your code to the module pattern (you should), then `window.x` is already what you want, whereas `var x` needs to be changed. – Keen May 30 '14 at 16:56
  • @GergoErdosi Yep, look like a duplicate. Good to know I've not been messing things up and limiting DOM pollution is a big concern. Thanks! I would give you credit for pointing me at the answer but it doesnt seem to let me accept comments as bet answer. If you move it below as an answer I'll do it. – Cyph May 30 '14 at 16:56
  • If it's early in your project's lifetime, I'd recommend `require.js` as your best bet for limiting namespace pollution. – Keen May 30 '14 at 16:58
  • 2
    If you are sure that there will be `window` object - I would recommend to use `window.x`. As you're writing a 3rd party script - no one can guarantee you in what context it'll be executed. It should be `window.x = window.x || {}` – Kiril May 30 '14 at 17:02
  • I've re-opened the question because the main difference between these two forms is not described in that duplicate at all because it's about how `x` is created, not how it is read. Answer below. – jfriend00 May 30 '14 at 17:05

1 Answers1

1

These two are not quite the same and the difference is not actually so much about reading the variable with window.x, but in how x is created. One works in strict mode, the other does not.

For the first one:

var x = x || {};

This is essentially the same as:

var x;
if (!x) x = {};

For the second approach:

x = window.x || {};

This is essentially the same as:

if (!window.x) x = {};

In the second one, window.x is required instead of just x because referencing an undefined variable in this way without the window. in front of it will cause an error. Besides that, the other main difference is that the first has:

var x;
x = {};

And, the second has just:

x = {};

This second model is implicitly creating a global variable without declaring it first which is not legal in strict mode.


So, the main functional difference here is not so much about reading via window.x, but assigning without declaring the variable using var and that difference is significant when running in strict mode. If you want your code to work in strict mode, then between these two choices, you have to use the first option because implicitly declared globals are not allowed in strict mode.

jfriend00
  • 683,504
  • 96
  • 985
  • 979