【问题标题】:What is "var _gaq = _gaq || []; " for?什么是“var _gaq = _gaq || [];”?
【发布时间】:2011-02-02 01:18:13
【问题描述】:

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 的全局对象?

【问题讨论】:

  • 另外值得注意的是,除非您实际上在同一页面中使用了两个 sn-ps(并且使用了错误的代码 - 实现多个跟踪器的方法要好得多,而不是简单地粘贴 sn- p 两次使用不同的帐户 ID),您可以安全地将这一行替换为 var _gaq = []。可以在此处找到更多可能的异步 Google Analytics sn-p 微优化:mathiasbynens.be/notes/async-analytics-snippet

标签: javascript google-analytics


【解决方案1】:

很抱歉回答晚了,但我阅读了接受的答案,我认为它错过了最重要的事情。因此,我将尝试解释我的理解:

首先,已经解释过了,但是答案需要完整所以我也解释一下,代码开头:

var _gaq = _gaq || [];

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

认为它是等价的:

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

undefined 的 javascript 值是“falsish”/“falsy”,即当转换为布尔值时它的计算结果为 false,因此在这种情况下,_gaq 用[] 初始化。

需要注意的是:

  • 如果 _gaq 在这个阶段包含一个数组,_gaq 是“真”,所以它会保持它的值(而不是被清空)
  • 如果 _gaq 在这个阶段包含另一种类型的对象,_gaq 也可以保持它的值

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

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

如果 _gaq 是一个数组,你都会猜到 ['command', 'argument'] 是追加到数组中的。谷歌分析将其存储在其队列中以供进一步处理。数组_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 sn-p 时。

【讨论】:

    【解决方案2】:

    编辑:

    我会添加更多细节

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

    然而,当 ga.js 脚本被加载时,google 会获取这个数组并将其转换为一个对象,供 ga 使用。

    这就是为什么您将函数推送到 _gaq 数组中,然后在您完成构建数组之后调用 ga.js 脚本。

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

    【讨论】:

      【解决方案3】:

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

      您还可以在简单的 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!
      

      这两种方式都更好看。

      语言允许这样做的原因是,如果左侧会使整条线无论如何都失败,那么评估右侧是浪费时间。所以它只是忽略它,除非它需要它。

      【讨论】:

      • 我更喜欢你的例子中的 if 语句,更易于阅读。
      【解决方案4】:

      此行允许在同一页面中使用多个 GA sn-ps。它确保第二个 sn-p 不会覆盖第一个定义的 _gaq。

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

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

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

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

      【讨论】:

        【解决方案5】:

        是的,它完全按照你的想法做 :) 它是

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

        【讨论】:

        • _gaq 变量本身是干什么用的,或者为这个变量分配一个空数组?看起来跟踪脚本使用 _gaq 全局变量来保存一些数据,然后再将它们发送到服务器。压缩后的源代码有点难以理解,但第一行有 var ba="_gaq" 和 var i = window[ba]; (返回 _gaq 全局变量)在最后一行。如果 _gaq 未定义,则将其设为数组只会使其可以在其上使用 .push() 方法。
        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

          • 如果 _gaq 之前声明但不是数组而是数字或字符串,它仍然会失败:)
          • 我对 '_gaq' 本身没有问题,但我在谷歌分析文档中没有发现关于有一个名为 _gaq 的变量的警告。
          • 这就像是对黑客的公开邀请,就像 robots.txt 一样。您可以将“请不要使用 xxx”解释为“我们的代码在您使用 xxx 时易受攻击”。 :-)
          • 好吧,如果 Google 确实发出了关于使用 _gaq 变量的警告,您难道不想尝试一下吗?就像 robots.txt 一样:如果您可以阅读它,并且它包含 Disallow: /admin/ 行,您不尝试将“/admin/”添加到 URL 以查看它的作用吗?
          • 没有文档说你不应该有一个名为 _gaq 的变量,但是如果你想使用 GA(包括非异步版本),你应该避免使用那个命名空间。
          猜你喜欢
          • 2011-03-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-05
          • 1970-01-01
          • 1970-01-01
          • 2011-03-26
          • 1970-01-01
          相关资源
          最近更新 更多