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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2538252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:48:04  来源:igfitidea点击:

What is "var _gaq = _gaq || []; " for?

javascriptgoogle-analytics

提问by

The Async Tracking code in Google Analytics looks like this:

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

About The first line:

关于第一行:

var _gaq = _gaq || []; 

I think it ensures that if _gaqis already defined we should use it otherwise we should an array.

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

Can anybody explain what this is for?

谁能解释一下这是干什么用的?

Also, does it matter if _gaqgets renamed? In other words, does Google Analytics rely on a global object named _gaq?

另外,如果_gaq改名有关系吗?换句话说,Google Analytics 是否依赖于一个名为 的全局对象_gaq

采纳答案by Victor

Yes, it ensures that _gaqis defined, so that _gaq.push()never fails.

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

I would not mess with the name of the variables in GA's code... do you have any reason to? Does it conflict with any of your variables? (Then I would change mine...)

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

回答by Brian

This line is there to allow multiple GA snippets in the same page. It ensures that the second snippet doesn't overwrite a _gaq defined by the first.

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

GA asynchronous tracking works by first defining _gaq as an array. This array acts like a queue, which allows you to push (append) configuration and tracking "commands" (like _trackPageview) onto the end of the queue. Your commands are stored in this array until ga.js fully downloads.

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

When ga.js is ready, it executes all the commands in the _gaq array and replaces _gaq with an object. This object also has a push method, but instead of queueing up commands, it executes them immediately, because ga.js is available to process them.

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

This mechanism allows you to make configuration and tracking commands without knowing if the browser has finished downloading ga.js. This is needed because the async snippet downloads ga.js without blocking other code on the page from running. Things would get hairy if that other code (your configuration commands) needed to know the state of ga.js being downloaded.

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

All of this absolutely doesdepend on the use of the name _gaq. You shouldn't try to name it if you want asynchronous tracking to work.

所有这一切都完全依赖于使用的名称_gaq的。如果您希望异步跟踪工作,您不应该尝试命名它。

回答by Tor Valamo

Using ||in assignment is a common programming trick which takes advantage of the evaluation direction of the operator, which is left to right. That means that it evaluates the left side first. Then, and only if that is false(or a false equivalent), does it evaluate the right side.

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

You can also take advantage of the ||or &&operators in a simple if statement, so that

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

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

if (!some_boolean) {
  do_b();
}

become

变得

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

which are both way nicer to look at.

这两种方式都更好看。

The reason languages allow this, is because it is a waste of time evaluating the right side if the left side will make the entire line fail anyways. So it just ignores it unless it's needed.

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

回答by dotpush

Sorry to answer late, but I read the accepted answer and I think that it misses the most important thing. So I'll try to explain what I understood :

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

First, it has been explained but the answer needs to be complete so I explain it too, the code begin with:

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

var _gaq = _gaq || [];

It ensures that _gaq is defined. If it is not defined, it is initialized to an empty array.

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

Think it like the equivalent:

把它想象成等价的:

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

The javascript value undefinedis "falsish"/"falsy", ie it evaluates to false when converted to a boolean, so _gaq is initialized with []in this case.

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

What's important to note is that :

需要注意的是:

  • if _gaq contains an array at this stage, _gaq is "trueish", so it will keep it's value (and not be emptied)
  • if _gaq contains another type of object at this stage, _gaq can also keep its value
  • 如果 _gaq 在此阶段包含一个数组,则 _gaq 是“真实的”,因此它将保留其值(并且不会被清空)
  • 如果_gaq在这个阶段包含另一种类型的对象,_gaq也可以保持它的值

Well, I re-explained, as well as I can, something already explained. Most people experienced with javascript had already understood it. However, the interesting part is not only the start!

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

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

If _gaq is an array, you will all guess that the item ['command', 'argument']is appended to the array. Google analytics store this in its queue for further processing. The array _gaq is used as a queue.

如果 _gaq 是一个数组,大家都会猜到 item['command', 'argument']是追加到数组中的。谷歌分析将其存储在其队列中以供进一步处理。数组 _gaq 用作队列。

But the really interesting part is that_gaq.push(/*...*/)can be done without having an array named _gaq. It is just a method call, and non arrays can also have a "push" method.

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

It "opens new possibilities". Here is a summary of one:

它“开辟了新的可能性”。这是一个总结:

  • As long as the external javascript file is not asynchronously loaded, _gaq is an array used as a queue.
  • The external ga.js then process the queue.
  • ga.js then replaces _gaq by an object which provides a push method.
  • Once _gaq is replaced by an object, the _gaq.push(/*...*/)commands don't need to be deferred anymore, they can be executed.
  • 只要外部javascript文件不是异步加载的,_gaq就是一个用作队列的数组。
  • 然后外部 ga.js 处理队列。
  • 然后 ga.js 将 _gaq 替换为一个提供 push 方法的对象。
  • 一旦 _gaq 被一个对象替换,_gaq.push(/*...*/)命令就不再需要被延迟,它们可以被执行。

For those who missed the asynchronous script loading part, it is:

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

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

Using temporarily an array as a queue and the push method is great code. It is a very interesting way to cope with the fact that when _gaq.push(/*...*/)is executed, we don't always now if the dependency has been asynchronously loaded yet or not.

临时使用数组作为队列和 push 方法是很棒的代码。这是一种非常有趣的方式来处理这样一个事实,即在_gaq.push(/*...*/)执行时,我们并不总是现在是否已经异步加载依赖项。

Another related interesting way of managing this kind of problems is the new Google Analytics "isogram" snippet: ga(/*...*/)looks even more intuitive for calls that _gaq.push(/*...*/), but it still copes with the joys related to loading dependencies in an asynchronous way.

管理此类问题的另一种相关有趣方法是新的 Google Analytics“isogram”片段ga(/*...*/)对于调用 that 看起来更加直观_gaq.push(/*...*/),但它仍然以异步方式处理与加载依赖项相关的乐趣。

Can anybody explain what this is for?

谁能解释一下这是干什么用的?

I hope my answer above has done it. What I wanted to share here is that the first line is done in a particular way to fit with the whole thing: initialization that never harms if done twice, smart use of push method...

我希望我上面的回答已经做到了。我想在这里分享的是,第一行是以一种特殊的方式完成的以适应整个事情:如果完成两次就不会造成伤害的初始化,推送方法的巧妙使用......

does Google Analytics rely on a global object named _gaq?

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

Yes it does, when using this ga.js snippet.

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

回答by duggi

EDIT:

编辑:

i will add more detail

我会添加更多细节

_gaq is simply a javascript array, as first defined. you add events to it, such as event tracking callbacks

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

when the ga.js script is loaded, however, google takes this array and turns it into an object, that ga uses.

但是,当加载 ga.js 脚本时,google 会获取此数组并将其转换为 ga 使用的对象。

this is why you push functions into the _gaq array, then call the ga.js script after you;re done constructing the array.

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

gaq is google analytics queue. it's a stack for GA methods, like event tracking, page attribution, etc. you use the push() method to put GA stuff on there. reduces event interference, everyone should do this, or at least learn the concept.

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

回答by pawel

Yes, it does exactly what you think it does :) It is a shorthand for

是的,它完全按照你的想法去做 :) 这是一个简写

if(!_gaq){ var _gaq = [] }

回答by Fabian

This means that if _gaq is already defined it use that else it declares an empty array. With push you can override settings. If the _gaq object wasnt defined the 2 "lines" after that would result in an error.

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

Yes the _gaq object is expect in the script which you include in the code there (ga.js).

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