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.