1

Checking a website I have come accross with this code;

if (!window.homePosition) window.homePosition = $('#sticky-container').offset().top;

is there any difference in declaring the global variable in this two ways?

window.homePosition = 400;

or

var homePosition = 400;

Why do you think the previous developer used this notation?

Mg Gm
  • 151
  • 1
  • 11
  • 2
    possible duplicate of [Javascript global variables](http://stackoverflow.com/questions/4862193/javascript-global-variables) – Clément Andraud Jul 18 '14 at 13:20
  • I would have gone for `if (typeof window.homePosition === 'undefined')` instead of `if (!window.homePosition)` – techfoobar Jul 18 '14 at 13:25
  • @techfoobar yes, though if the code knows it's supposed to be an object reference then that might be OK. We don't know much about the code in question, of course. – Pointy Jul 18 '14 at 13:29
  • @Pointy - Ofcourse. I was referring to the case where the code was checking to see if it was already defined (not by itself). Otherwise, yes. – techfoobar Jul 18 '14 at 13:31
  • the code is wrapped up in a very small function that is triggered on window scroll. The function is within the global scope – Mg Gm Jul 18 '14 at 13:33
  • @MgGm that's what I assumed. The "right way" to do it is to make an explicit reference to the global context. A `var` declaration inside such a function creates a *local* variable. – Pointy Jul 18 '14 at 13:44

2 Answers2

2

Yes, there are two differences, though in practical terms they're not usually big ones.

Your have 3 statements

var a=0;

...creates a variable on the variable object for the global execution context, which is the global object, which on browsers is aliased as window (and is a DOM window object rather than just a generic object as it would be on non-browser implementations). The symbol window is, itself, actually a property of the global (window) object that it uses to point to itself.

The upshot of all that is: It creates a property on window that you cannot delete. It's also defined before the first line of code runs (see "When var happens" below).

Note that on IE8 and earlier, the property created on window is not enumerable (doesn't show up in for..in statements). In IE9, Chrome, Firefox, and Opera, it's enumerable.


a=0;

...creates a property on the window object implicitly. As it's a normal property, you can delete it. I'd recommend not doing this, it can be unclear to anyone reading your code later.

And interestingly, again on IE8 and earlier, the property created not enumerable (doesn't show up in for..in statements). That's odd, particularly given the below.


window.a=0;

...creates a property on the window object explicitly. As it's a normal property, you can delete it.

This property is enumerable, on IE8 and earlier, and on every other browser I've tried.

Clément Andraud
  • 9,103
  • 25
  • 80
  • 158
  • I think all the answers were very informative and extremely useful to me. But I have found this to be the most in-depth explanation, and also the complexity does not get in the way with my understanding – Mg Gm Jul 18 '14 at 14:35
-3

From code that's inside a function, the only way to create a global variable is to create a property on the global object (which, in a browser, is window).

Lots of code, especially libraries but in general well-written code, will be encapsulated in a function for the explicit purpose of avoiding the creation of global symbols:

(function() {
  "use strict";

  // lots of code here

})();

From inside such code, if it's desired that a global symbol be exported, the way to do that is to create a property of the global context:

(function() {
  "use strict";

  // lots of code here

  window.something = valueToExport;

})();

Typically such encapsulating functions are written such that a local copy of a reference to the global context is available:

(function(global) {
  "use strict";

  // lots of code here

  global.something = valueToExport;

})(this);

That works because in the actual global context — where that encapsulating function runs — the value of this is a reference to that context (window in a browser). In the above example, then, the parameter global will be a local reference to the global context object.

edit — without "strict" mode, a reference to an otherwise undeclared symbol on the left side of an assignment will, it's true, create a global symbol. The question on this page is, "How to declare global variables in JavaScript the right way." Using implicit global property creation is definitely not the right way. In "strict" mode — which all newly-written code should be using — it's an error.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    your first sentence is just not true. – mb21 Jul 18 '14 at 13:23
  • @mb21 in what way is it not true? How would you create a global variable from inside a function? *edit* ah, by implicit reference - well that's erroneous in "strict" mode, and a really bad practice in any case. – Pointy Jul 18 '14 at 13:24
  • While unfortunate, I wouldn't assume that everybody is writing `'use strict';` – mb21 Jul 18 '14 at 13:36
  • @mb21 generally I'd agree, but we're answering a question about the "right way" to do something. – Pointy Jul 18 '14 at 13:43