7

Google Analytics 最初使用_gaq [object Array]. 将数组传递给函数在 JavaScript 中是通过引用传递对象。

编辑:正如答案中所指出的,引用是按值传递的。有关在 JavaScript 中传递引用/值的更多详细信息,请参见https://stackoverflow.com/a/5314911/120521 。)

下面的代码使用 jQuery 等待 DOM 加载,然后附加一个事件,一旦用户更改字段,该change事件将向 Google Analytics 发送虚拟页面浏览量。<input/>

var _gaq = _gaq || [];
_gaq.push(['_setAccount', _gAAccount]);
_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 Tracking = {
  trackInputs: function ($, gaObject) {
    var inputs = $('#signUp').find('input');
    inputs.bind('change', function () {
      gaObject.push(['_trackPageview', '/virtual/input']);
      console.log(gaObject); // Outputs:
                         // [Array[2], Array[1], Array[2]]
                         // i.e. _setAccount, _trackPageview,
                         // and _trackPageview calls.
    });
  }
};

jQuery(document).ready(function($) {
  Tracking.trackInputs($, _gaq);
});

// ... DOM begins below

但是,从上面的评论中可以看出,该trackInputs()方法打印了“原始”数组。通常,Google Analytics 脚本所做的是将_gaq数组更改为_gaq对象并更改对象的推送原型,以便在向对象推送新调用时向 Google Analytics 服务器发出请求。

为什么这种改变也不是通过引用传递到的trackInputs()

我意识到加载的谷歌分析脚本将(或者会?)在Tracking.trackInputs()定义之后发生,所以浏览器可能不理解它现在是一个[object object]但会坚持认为它是原始的[object Array]. 但是,那么它不再是参考,是吗?

(全局使用_gaq对象(根本不将其传递给方法)可以解决问题,但我想了解为什么这不起作用。)

4

4 回答 4

5
jQuery(document).ready(function($) {
  Tracking.trackInputs($, _gaq);
});

由于在加载 GA之前_gaqDOM 已准备好,因此 的引用仍然指向一个普通数组,然后由函数gaObject内部的本地符号永久保存。trackInputs()

trackInputs: function ($, gaObject) {

GA 加载后,全局符号_gaq被跟踪器替换,但gaObject仍指向旧符号。

您可以使用 GA 的“就绪”功能来调用您的trackInputs()函数,而不是使用$(document).ready(...)

_gaq.push(function() {
    // when this runs, the tracker would have initialized;
    Tracking.trackInputs($, _gaq);
});
于 2013-03-11T12:44:44.893 回答
3

Google Analytics 最初使用 _gaq [对象数组]。将数组传递给函数在 JavaScript 中是通过引用传递对象。

您最初的假设是不正确的。Javascript 总是使用按值传递。按值传递。按价值传递。

您正在通过value传递对对象的引用。引用按值传递。归根结底,您有许多对一个底层数组的引用,因为每次按值传递引用时, 您都有一个新的引用副本,但对象永远不会改变。

通常,Google Analytics 脚本所做的是将 _gaq 数组更改为 _gaq 对象,并更改对象的推送原型,使其在向对象推送新调用时向 Google Analytics 服务器发出请求。

它在哪里这样做?

但是,从上面的评论中可以看出,trackInputs() 方法会打印“原始”数组。

当然可以。

var _gaq = _gaq || [];
_gaq.push(['_setAccount', _gAAccount]);
_gaq.push(['_trackPageview']);

定义和排列并将东西放入其中。

jQuery(document).ready(function($) {
  Tracking.trackInputs($, _gaq);
});

将该数组按值传递给方法

var Tracking = {
  trackInputs: function ($, gaObject) {
    ...
    inputs.bind('change', function () {
      gaObject.push(['_trackPageview', '/virtual/input']);
      ...
    });
  }
};

在 gaObject 周围创建一个闭包,它是对原始数组的引用,并在更改处理程序中使用它。它与引用不同_gaq,它是该引用的副本,但它指向同一个数组。

于 2013-03-11T12:30:14.900 回答
0

冒着说出愚蠢的话的风险,因为我一直盯着你的脚本大约 20 分钟,没有什么明显的东西跳出来……它是否有可能按预期工作,但是你的测试用例被打折了分析作为您自己的 IP 地址列在配置文件过滤器下?

于 2013-03-11T12:25:03.697 回答
0
jQuery(document).ready(function() {
  _gaq.push(function() {
    Tracking.trackInputs($, _gaq);
  });
});
于 2013-03-11T12:54:05.230 回答