什么是“var _gaq = _gaq || [];”for?

时间:2010-03-29 13:40:22

标签: javascript google-analytics

Google Analytics中的异步跟踪代码如下所示:

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); 
})(); 

关于第一行:

var _gaq = _gaq || []; 

我认为它确保如果_gaq已经定义,我们应该使用它,否则我们应该使用数组。

有人可以解释这是为了什么吗?

此外,重命名_gaq是否重要?换句话说,Google Analytics依赖于名为_gaq的全局对象?

7 个答案:

答案 0 :(得分:24)

此行允许在同一页面中显示多个GA代码段。它确保第二个片段不会覆盖第一个片段定义的_gaq。

GA异步跟踪的工作原理是首先将_gaq定义为数组。这个数组就像一个队列,它允许你推送(追加)配置和跟踪“命令”(如_trackPageview)到队列的末尾。您的命令存储在此数组中,直到ga.js完全下载。

当ga.js准备就绪时,它会执行_gaq数组中的所有命令,并用对象替换_gaq。此对象也有一个push方法,但它不是排队命令,而是立即执行它们,因为ga.js可用于处理它们。

此机制允许您在不知道浏览器是否已完成下载ga.js的情况下进行配置和跟踪命令。这是必需的,因为异步代码段会下载ga.js而不会阻止页面上的其他代码运行。如果其他代码(您的配置命令)需要知道正在下载的ga.js的状态,事情会变得毛茸茸。

所有这些绝对确实取决于名称_gaq的使用。如果希望异步跟踪能够工作,则不应尝试命名。

答案 1 :(得分:15)

是的,它确保定义_gaq,以便_gaq.push()永远不会失败。

我不会弄乱GA代码中的变量名称......你有什么理由吗?它与您的任何变量冲突吗? (然后我会改变我的......)

答案 2 :(得分:13)

在赋值中使用||是一种常见的编程技巧,它利用了从左到右的运算符的评估方向。这意味着它首先评估左侧。然后,只有当它是假的(或错误的等价物)时,它是否会评估右侧。

您还可以在简单的if语句中利用||&&运算符,以便

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

if (!some_boolean) {
  do_b();
}

成为

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

这两种方式都更好看。

语言允许的原因是因为如果左侧将使整条线路无论如何都是浪费时间来评估右侧。除非需要,否则它会忽略它。

答案 3 :(得分:3)

编辑:

我会添加更多细节

_gaq只是一个javascript数组,如首先定义的那样。您向其添加事件,例如事件跟踪回调

加载ga.js脚本时,google会将此数组转换为ga使用的对象。

这就是你将函数推入_gaq数组,然后在你之后调用ga.js脚本的原因;重新构建数组。

gaq是谷歌分析队列。它是GA方法的堆栈,如事件跟踪,页面归因等。您使用push()方法将GA内容放在那里。减少事件干扰,每个人都应该这样做,或至少学习这个概念。

答案 4 :(得分:3)

很抱歉回答很晚,但我读了接受的答案,我认为它错过了最重要的事情。所以我会试着解释一下我的理解:

首先,它已被解释,但答案需要完整,所以我也解释它,代码开头:

var _gaq = _gaq || [];

确保定义_gaq。如果未定义,则将其初始化为空数组。

将其视为等效物:

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

javascript值undefined是“falsish”/“falsy”,即在转换为布尔值时评估为false,因此在这种情况下_gaq用[]初始化。

值得注意的是:

  • 如果_gaq在这个阶段包含一个数组,_gaq是“真实的”,所以它将保持它的值(并且不会被清空)
  • 如果_gaq在此阶段包含其他类型的对象,_gaq也可以保留其值

好吧,我尽可能地解释了已经解释过的事情。大多数使用javascript的人都已经理解了它。 然而,有趣的部分不仅仅是开始!

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

如果_gaq是一个数组,你都会猜到项['command', 'argument']被附加到数组中。 Google Analytics将其存储在队列中以进行进一步处理。数组_gaq用作队列。

但真正有趣的部分是_gaq.push(/*...*/)可以在没有名为_gaq的数组的情况下完成。它只是一个方法调用,非数组也可以使用“push”方法。

它“开启了新的可能性”。以下是一个摘要:

  • 只要外部javascript文件没有异步加载,_gaq就是一个用作队列的数组。
  • 外部ga.js然后处理队列。
  • ga.js然后用提供推送方法的对象替换_gaq。
  • 将_gaq替换为对象后,_gaq.push(/*...*/)命令不再需要延迟,可以执行它们。

对于那些错过了异步脚本加载部分的人来说,它是:

(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); 
})();

暂时使用数组作为队列,push方法很棒。这是一种非常有趣的方式来应对这样一个事实:当执行_gaq.push(/*...*/)时,如果依赖关系已被异步加载,我们现在并不总是这样。

管理此类问题的另一个有趣的方法是new Google Analytics "isogram" snippetga(/*...*/)_gaq.push(/*...*/)的调用看起来更直观,但它仍然可以应对与加载依赖关系相关的欢乐以异步方式。

  

有人可以解释这是为了什么吗?

我希望我上面的答案已经完成了。我想在这里分享的是,第一行是以特定的方式完成以适应整个事情:初始化,如果做了两次永远不会伤害,聪明地使用推送方法......

  

Google Analytics依赖于名为_gaq的全局对象吗?

是的,当使用此ga.js片段时。

答案 5 :(得分:2)

是的,它完全符合你的想法:) 这是

的简写
if(!_gaq){ var _gaq = [] }

答案 6 :(得分:0)

这意味着如果已经定义了_gaq,则使用else,它声明一个空数组。使用推送,您可以覆盖设置。如果没有定义_gaq对象,那么之后的2“行”将导致错误。

是的,_gaq对象在您在代码中包含的脚本中是预期的(ga.js)。