What is “var _gaq = _gaq || []; ” for?

The Async Tracking code in Google Analytics looks like this:

var _gaq = _gaq || []; 
_gaq.push(['_setAccount', 'UA-XXXXX-X']); 
_gaq.push(['_trackPageview']); 

(function() { 
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 
})(); 

About The first line:

var _gaq = _gaq || []; 

I think it ensures that if _gaq is already defined we should use it otherwise we should an array.

Can anybody explain what this is for?

Also, does it matter if _gaq gets renamed? In other words, does Google Analytics rely on a global object named _gaq?

Answers:

Answer

Yes, it ensures that _gaq is defined, so that _gaq.push() never fails.

I would not mess with the name of the variables in GA's code... do you have any reason to? Does it conflict with any of your variables? (Then I would change mine...)

Answer

This line is there to allow multiple GA snippets in the same page. It ensures that the second snippet doesn't overwrite a _gaq defined by the first.

GA asynchronous tracking works by first defining _gaq as an array. This array acts like a queue, which allows you to push (append) configuration and tracking "commands" (like _trackPageview) onto the end of the queue. Your commands are stored in this array until ga.js fully downloads.

When ga.js is ready, it executes all the commands in the _gaq array and replaces _gaq with an object. This object also has a push method, but instead of queueing up commands, it executes them immediately, because ga.js is available to process them.

This mechanism allows you to make configuration and tracking commands without knowing if the browser has finished downloading ga.js. This is needed because the async snippet downloads ga.js without blocking other code on the page from running. Things would get hairy if that other code (your configuration commands) needed to know the state of ga.js being downloaded.

All of this absolutely does depend on the use of the name _gaq. You shouldn't try to name it if you want asynchronous tracking to work.

Answer

Using || in assignment is a common programming trick which takes advantage of the evaluation direction of the operator, which is left to right. That means that it evaluates the left side first. Then, and only if that is false (or a false equivalent), does it evaluate the right side.

You can also take advantage of the || or && operators in a simple if statement, so that

if (a > 5) {
  do_a();
}

if (!some_boolean) {
  do_b();
}

become

a > 5 && do_a();
some_boolean || do_b(); // Note that the negation operator `!` is gone!

which are both way nicer to look at.

The reason languages allow this, is because it is a waste of time evaluating the right side if the left side will make the entire line fail anyways. So it just ignores it unless it's needed.

Answer

EDIT:

i will add more detail

_gaq is simply a javascript array, as first defined. you add events to it, such as event tracking callbacks

when the ga.js script is loaded, however, google takes this array and turns it into an object, that ga uses.

this is why you push functions into the _gaq array, then call the ga.js script after you;re done constructing the array.

gaq is google analytics queue. it's a stack for GA methods, like event tracking, page attribution, etc. you use the push() method to put GA stuff on there. reduces event interference, everyone should do this, or at least learn the concept.

Answer

Sorry to answer late, but I read the accepted answer and I think that it misses the most important thing. So I'll try to explain what I understood :

First, it has been explained but the answer needs to be complete so I explain it too, the code begin with:

var _gaq = _gaq || [];

It ensures that _gaq is defined. If it is not defined, it is initialized to an empty array.

Think it like the equivalent:

var _gaq;
/* ... */
if(!_gaq)
  _gaq = [];

The javascript value undefined is "falsish"/"falsy", ie it evaluates to false when converted to a boolean, so _gaq is initialized with [] in this case.

What's important to note is that :

  • if _gaq contains an array at this stage, _gaq is "trueish", so it will keep it's value (and not be emptied)
  • if _gaq contains another type of object at this stage, _gaq can also keep its value

Well, I re-explained, as well as I can, something already explained. Most people experienced with javascript had already understood it. However, the interesting part is not only the start!

_gaq.push(['command', 'argument']); // is very interesting too

If _gaq is an array, you will all guess that the item ['command', 'argument'] is appended to the array. Google analytics store this in its queue for further processing. The array _gaq is used as a queue.

But the really interesting part is that_gaq.push(/*...*/) can be done without having an array named _gaq. It is just a method call, and non arrays can also have a "push" method.

It "opens new possibilities". Here is a summary of one:

  • As long as the external javascript file is not asynchronously loaded, _gaq is an array used as a queue.
  • The external ga.js then process the queue.
  • ga.js then replaces _gaq by an object which provides a push method.
  • Once _gaq is replaced by an object, the _gaq.push(/*...*/) commands don't need to be deferred anymore, they can be executed.

For those who missed the asynchronous script loading part, it is:

(function() { 
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; 
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); 
})();

Using temporarily an array as a queue and the push method is great code. It is a very interesting way to cope with the fact that when _gaq.push(/*...*/) is executed, we don't always now if the dependency has been asynchronously loaded yet or not.

Another related interesting way of managing this kind of problems is the new Google Analytics "isogram" snippet: ga(/*...*/) looks even more intuitive for calls that _gaq.push(/*...*/), but it still copes with the joys related to loading dependencies in an asynchronous way.

Can anybody explain what this is for?

I hope my answer above has done it. What I wanted to share here is that the first line is done in a particular way to fit with the whole thing: initialization that never harms if done twice, smart use of push method...

does Google Analytics rely on a global object named _gaq?

Yes it does, when using this ga.js snippet.

Answer

Yes, it does exactly what you think it does :) It is a shorthand for

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

This means that if _gaq is already defined it use that else it declares an empty array. With push you can override settings. If the _gaq object wasnt defined the 2 "lines" after that would result in an error.

Yes the _gaq object is expect in the script which you include in the code there (ga.js).

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.