为什么不通过引用方法传递原型更改?

时间:2013-03-11 10:38:35

标签: javascript jquery google-analytics

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

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

以下代码使用jQuery等待DOM加载,然后附加change事件,该事件会在用户更改<input/>字段后向Google Analytics发送虚拟综合浏览量。

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

我意识到加载的Google Analytics脚本将会(或将会?)在Tracking.trackInputs()定义之后发生,因此浏览器可能无法理解它现在是[object object],但会坚持认为它是原[object Array]。但是,它不再是一个参考,是吗?

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

4 个答案:

答案 0 :(得分:5)

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

由于在加载GA之前DOM已准备好_gaq的引用仍指向普通数组,然后由本地符号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);
});

答案 1 :(得分:3)

  

Google Analytics最初使用_gaq [object Array]。通过   数组到函数是在JavaScript中传递一个对象,因此通过   参考

您的初步推定是不正确的。 Javascript总是使用pass by value。通过价值。通过价值。

您正在通过值传递对象的引用。引用通过BY 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的引用不同,它是该引用的副本,但它指向同一个数组。

答案 2 :(得分:0)

冒着说傻话的风险,因为我一直盯着你的剧本大约20分钟,没有什么明显的东西向我跳出来...它是否完全可能它按预期工作但是你的测试用例在Google Analytics上打折,因为您自己的IP地址列在profile filters下?

答案 3 :(得分:0)

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