This works in the case with 'var' because the variable-stop in the scope resolution is created. Without the 'var' you just run off looking through the scope chains and you get told. If you really want to use a global variable:
// This is fine because assignment always sets a property value
// in this case (no 'var ga') it's the same as window.ga = window.ga || []
ga = window.ga || []
Or:
// Once again, only the lookup is affected with "running off"
// the lookup chain. It's not that the variable has no value --
// the problem is there IS NO VARIABLE.
if (!window.ga) {
ga = []
}
Or even this:
// First line is the same as window.ga = window.ga,
// but now the property ga is guaranteed to exist on the window object --
// the VALUE of the property may (still) be undefined
ga = window.ga
ga = ga || []
Note that in both these cases I explicitly invoked ga
as a property of the window
(global) object.
You can read about the details here: Identifier Resolution, Execution Contexts and Scope Chains.
The placement of var within a scope does not matter. All of the following are the same:
var ga
ga = ga || []
var ga = ga || []
ga = ga || []
var ga