15

From the google analytics tracking code:

var _gaq = _gaq || [];

how does this work?

Is it a conditional variable value assignment? Is it the same as saying:

if( !(_gaq) ) {_gaq = []; }

?

afaf12
  • 5,163
  • 9
  • 35
  • 58
mikkelbreum
  • 3,021
  • 9
  • 38
  • 41
  • possible duplicate of [What does the || operator do?](http://stackoverflow.com/questions/830618/what-does-the-operator-do) – Felix Kling May 29 '11 at 13:08
  • Short answer: yes (although the second one creates a global `_gaq` *edit:* if we assume that `_gaq` does not exist). – Felix Kling May 29 '11 at 13:08
  • @Felix — unless something else applies a different scope to `_gaq` – Quentin May 29 '11 at 13:12
  • I would add that given the specifics of this questions, those two statements also differ in that you cannot use the syntax of the former to conditionally define a global variable as it will throw a reference error. – Andrew Hubbs Mar 15 '12 at 20:26
  • Also worth noting is that if you had purposely set `_gaq` to a falsy value (like `0`), then it would be reassigned the value of `[]`. So it doesn't behave exactly like conditional assignment in Ruby. – steve May 10 '12 at 07:53

4 Answers4

15

The or operator (||) will return the left hand side if it is a true value, otherwise it will return the right hand side.

It is very similar to your second example, but since it makes use of the var keyword, it also establishes a local scope for the variable.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
5

Yes, it is.

The || operator evaluates to its leftmost "truthy" operand.
If _gaq is "falsy" (such as null, undefined, or 0), it will evaluate to the right side ([]).

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
2

It's the same as saying:

if( !(_gaq) ) {var _gaq = [];}

(This can be done since the var is hoisted above the conditional check, thereby avoiding a 'not defined' error, and it will also cause _gaq to be automatically treated as local in scope.)

Brett Zamir
  • 14,034
  • 6
  • 54
  • 77
1

Actually it's not the same as saying:

if (!_gaq) _gaq = [];

at least not necessarily. Consider this:

function outer() {
  var _gaq = null;
  function inner() {
    var _gaq = _gaq || [];
    // ...
  }

  inner();
  _gaq = 1;
  inner();
}

When there's a "_gaq" (I hate typing that, by the way) in an outer lexical scope, what you end up with is a new variable in the inner scope. The "if" statement differs in that very important way — there would only be one "_gaq" in that case.

Pointy
  • 405,095
  • 59
  • 585
  • 614