Для чего нужен «var _gaq = _gaq || [];»? - PullRequest
46 голосов
/ 29 марта 2010

Код асинхронного отслеживания в 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?

Ответы [ 7 ]

25 голосов
/ 30 марта 2010

Эта строка предназначена для разрешения нескольких фрагментов GA на одной странице. Это гарантирует, что второй фрагмент не перезапишет _gaq, определенный первым.

Асинхронное отслеживание GA работает, сначала определив _gaq как массив. Этот массив действует как очередь, что позволяет вам помещать (добавлять) конфигурационные и отслеживающие «команды» (например, _trackPageview) в конец очереди. Ваши команды хранятся в этом массиве до полной загрузки ga.js.

Когда ga.js готов, он выполняет все команды в массиве _gaq и заменяет _gaq объектом. Этот объект также имеет метод push, но вместо того, чтобы ставить команды в очередь, он выполняет их немедленно, поскольку ga.js доступен для их обработки.

Этот механизм позволяет вам выполнять команды настройки и отслеживания, не зная, завершил ли браузер загрузку ga.js. Это необходимо, потому что асинхронный фрагмент загружает ga.js, не блокируя запуск другого кода на странице. Все могло бы стать неприятным, если бы этот другой код (ваши команды конфигурации) должен был знать состояние загружаемого ga.js.

Все это абсолютно зависит от использования имени _gaq. Вы не должны пытаться назвать его, если хотите, чтобы асинхронное отслеживание работало.

15 голосов
/ 29 марта 2010

Да, это гарантирует, что _gaq определено, так что _gaq.push() никогда не завершится неудачей.

Я бы не стал связываться с именами переменных в коде GA ... У вас есть причины? Это конфликтует с любой из ваших переменных? (Тогда я бы изменил мой ...)

13 голосов
/ 29 марта 2010

Использование || в присваивании является распространенным приемом программирования, который использует преимущество направления оценки оператора, которое слева направо. Это означает, что он сначала оценивает левую сторону. Тогда и только если это ложно (или ложный эквивалент), оценивает ли оно правильную сторону.

Вы также можете воспользоваться операторами || или && в простом операторе if, так что

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

if (!some_boolean) {
  do_b();
}

1011 * стать *

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

, на которые так приятно смотреть.

Причина, по которой языки допускают это, заключается в том, что оценка правой стороны является пустой тратой времени, если левая сторона все равно приведет к сбою всей строки. Так что он просто игнорирует его, если только он не нужен.

3 голосов
/ 10 декабря 2014

Извините, что отвечаю поздно, но я прочитал принятый ответ и думаю, что он упускает самое главное. Поэтому я попытаюсь объяснить, что я понял:

Во-первых, это было объяснено, но ответ должен быть полным, поэтому я тоже объясняю, код начинается с:

var _gaq = _gaq || [];

Это гарантирует, что _gaq определен. Если он не определен, он инициализируется в пустой массив.

Думайте как эквивалент:

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

Значение javascript undefined равно "falsish" / "falsy", то есть при преобразовании в логическое значение оно принимает значение false, поэтому _gaq инициализируется [] в этом случае.

Важно отметить, что:

  • если на этом этапе _gaq содержит массив, _gaq имеет значение "trueish", поэтому он сохранит свое значение (и не будет очищен)
  • если на этом этапе _gaq содержит другой тип объекта, _gaq также может сохранить его значение

Ну, я как-то объяснил, как я уже объяснил, кое-что уже объяснил. Большинство людей, знакомых с javascript, уже поняли это. Однако интересная часть - это не только начало!

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

Если _gaq - это массив, вы все догадаетесь, что элемент ['command', 'argument'] добавлен в массив. Google Analytics хранит это в своей очереди для дальнейшей обработки. Массив _gaq используется в качестве очереди.

Но действительно интересной частью является то, что _gaq.push(/*...*/) может быть сделано без массива с именем _gaq. Это просто вызов метода, и у не массивов также может быть метод "push".

Это «открывает новые возможности». Вот краткое изложение одного:

  • Пока внешний файл javascript не загружен асинхронно, _gaq - это массив, используемый в качестве очереди.
  • Затем внешний ga.js обрабатывает очередь.
  • ga.js затем заменяет _gaq объектом, который предоставляет метод push.
  • Как только _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(/*...*/) мы теперь не всегда можем определить, была ли зависимость загружена асинхронно или нет.

Другим интересным способом решения подобных проблем является новый фрагмент изограммы Google Analytics : ga(/*...*/) выглядит еще более интуитивно понятным для вызовов, чем _gaq.push(/*...*/), но он по-прежнему справляется с радостями связанные с загрузкой зависимостей асинхронным способом.

Кто-нибудь может объяснить, для чего это?

Я надеюсь, что мой ответ выше сделал это. Я хотел бы поделиться здесь тем, что первая строка сделана особым образом, чтобы соответствовать целиком: инициализация, которая никогда не наносит вреда, если выполняется дважды, умное использование метода push ...

использует ли Google Analytics глобальный объект с именем _gaq?

Да, при использовании этого фрагмента ga.js.

3 голосов
/ 08 июня 2010

EDIT:

Я добавлю больше деталей

_gaq - это просто массив javascript, как определено вначале. вы добавляете к нему события, такие как обратные вызовы отслеживания событий

когда загружается скрипт ga.js, Google берет этот массив и превращает его в объект, который использует ga.

именно поэтому вы помещаете функции в массив _gaq, а затем вызываете скрипт ga.js после того, как закончите создание массива.

gaq - это очередь Google Analytics. это стек для методов GA, таких как отслеживание событий, атрибуция страниц и т. д. Вы используете метод push (), чтобы поместить туда элементы GA. уменьшает вмешательство событий, каждый должен сделать это или, по крайней мере, изучить концепцию.

2 голосов
/ 29 марта 2010

Да, это именно то, что вы думаете :) Это сокращение для

if(!_gaq){ var _gaq = [] }
0 голосов
/ 29 марта 2010

Это означает, что если _gaq уже определен, он использует, иначе он объявляет пустой массив. Нажатием вы можете изменить настройки. Если объект _gaq не был определен, две "строки" после этого приведут к ошибке.

Да, объект _gaq ожидается в сценарии, который вы включили в код (ga.js).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...