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

Dav*_*son 7 javascript jquery google-analytics

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

(编辑:正如答案中所指出的,引用是按值传递的.有关JavaScript中引用/值传递的更多详细信息,请参阅/sf/answers/372043801/.)

下面的代码使用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
Run Code Online (Sandbox Code Playgroud)

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

为什么这个改动也没有通过引用传递给trackInputs()

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

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

Ja͢*_*͢ck 5

jQuery(document).ready(function($) {
  Tracking.trackInputs($, _gaq);
});
Run Code Online (Sandbox Code Playgroud)

由于在加载GA 之前 DOM已准备就绪,_gaq静止引用指向普通数组,然后由函数gaObject内的局部符号延续trackInputs().

trackInputs: function ($, gaObject) {
Run Code Online (Sandbox Code Playgroud)

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

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

_gaq.push(function() {
    // when this runs, the tracker would have initialized;
    Tracking.trackInputs($, _gaq);
});
Run Code Online (Sandbox Code Playgroud)


hvg*_*des 3

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

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

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

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

它在哪里做到这一点?

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

当然可以。

var _gaq = _gaq || [];
_gaq.push(['_setAccount', _gAAccount]);
_gaq.push(['_trackPageview']);
Run Code Online (Sandbox Code Playgroud)

定义并排列并将内容放入其中。

jQuery(document).ready(function($) {
  Tracking.trackInputs($, _gaq);
});
Run Code Online (Sandbox Code Playgroud)

按值将该数组传递给方法

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

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