web-dev-qa-db-ja.com

「var _gaq = _gaq || [];」とは何ですか?

Googleアナリティクスの非同期トラッキングコードは次のようになります。

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

約1行目:

var _gaq = _gaq || []; 

_gaqが既に定義されている場合、それを使用する必要があり、そうでない場合は配列を使用する必要があると思います。

誰がこれが何のためにあるのか説明できますか?

また、_gaqの名前が変更されても問題はありませんか?つまり、Google Analyticsは_gaqという名前のグローバルオブジェクトに依存していますか?

46
user304246

はい、_gaq.Push()が失敗しないように、_gaqが定義されていることを確認します。

GAのコード内の変数の名前を台無しにしないでください...何か理由はありますか?それはあなたの変数のいずれかと競合しますか? (それから私は私のものを変えるでしょう...)

15
Victor

この行は、同じページで複数のGAスニペットを許可するためにあります。2番目のスニペットが最初のスニペットで定義された_gaqを上書きしないようにします。

GA非同期追跡は、最初に_gaqを配列として定義することにより機能します。この配列はキューのように機能し、キューの最後に構成と追跡「コマンド」(_trackPageviewなど)をプッシュ(追加)できます。 ga.jsが完全にダウンロードされるまで、コマンドはこの配列に保存されます。

Ga.jsの準備ができると、_gaq配列内のすべてのコマンドを実行し、_gaqをオブジェクトに置き換えます。このオブジェクトにはPushメソッドもありますが、ga.jsを使用してコマンドを処理できるため、コマンドをキューに入れる代わりにすぐに実行します。

このメカニズムにより、ブラウザがga.jsのダウンロードを終了したかどうかを知らなくても、構成および追跡コマンドを作成できます。これは、非同期スニペットがページ上の他のコードの実行をブロックせずにga.jsをダウンロードするために必要です。他のコード(設定コマンド)がダウンロードされているga.jsの状態を知る必要がある場合、事態は困難になります。

これらすべては、絶対にdoes _gaqという名前の使用に依存します。非同期追跡を機能させる場合は、名前を付けないでください。

25
Brian

割り当てで||を使用することは、左から右への演算子の評価方向を利用する一般的なプログラミングトリックです。つまり、左側を最初に評価します。次に、-それがfalseの場合のみ(またはfalseと同等)、右側を評価します。

単純なifステートメントで||または&&演算子を利用することもできます。

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

if (!some_boolean) {
  do_b();
}

なる

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

どちらも見た目が良いです。

言語がこれを許可する理由は、左側が行全体をとにかく失敗させる場合、右側を評価するのは時間の無駄だからです。そのため、必要でない限り無視します。

13
Tor Valamo

編集:

詳細を追加します

_gaqは、最初に定義されたように、単にJavaScript配列です。イベントトラッキングコールバックなどのイベントを追加します

ただし、ga.jsスクリプトが読み込まれると、googleはこの配列を受け取り、gaが使用するオブジェクトに変換します。

これが関数を_gaq配列にプッシュし、配列の作成が完了したらga.jsスクリプトを呼び出す理由です。

gaqはgoogle分析キューです。イベントトラッキング、ページ属性などのGAメソッドのスタックです。Push()メソッドを使用してGAの要素を配置します。イベントの干渉を減らすには、誰もがこれを行うか、少なくとも概念を学ぶ必要があります。

3
duggi

遅く答えて申し訳ありませんが、受け入れられた答えを読んで、最も重要なことを見逃していると思います。それで、私が理解したことを説明しようとします:

最初に、それは説明されましたが、答えは完全である必要があるので、私もそれを説明します、コードは:

_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アナリティクスは、これをさらに処理するためにキューに保存します。配列_gaqはキューとして使用されます。

しかし、本当に興味深いのは、_gaqという名前の配列がなくても、_gaq.Push(/*...*/)を実行できることです。これは単なるメソッド呼び出しであり、非配列は「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アナリティクスの「アイソグラム」スニペットga(/*...*/)は、_gaq.Push(/*...*/)の呼び出しに対してさらに直感的に見えますが、依存関係を非同期でロードすることに関連する喜びに対応しています。

誰がこれが何のためにあるのか説明できますか?

上記の私の答えがそれをしたことを願っています。ここで共有したかったのは、最初の行が特定の方法ですべてに合うように行われていることです:2回実行しても害を及ぼさない初期化、Pushメソッドのスマートな使用...

google Analyticsは_gaqという名前のグローバルオブジェクトに依存していますか?

はい、このga.jsスニペットを使用する場合はそうです。

3
dotpush

はい、それはあなたが思うように正確に行います:)

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

これは、_gaqが既に定義されている場合、空の配列を宣言する他の_gaqを使用することを意味します。プッシュを使用すると、設定を上書きできます。 _gaqオブジェクトが定義されていなかった場合、その後の2つの「行」はエラーになります。

はい。_gaqオブジェクトは、そこにあるコード(ga.js)に含めるスクリプトに含まれています。

0
Fabian