宣言されていない変数を読み取ることはできません。それが_gaq || []、最後のケースの式で試みていることです。
この場合
_gaq = _gaq || [];
_qaq以前に宣言されておらず、右側 ( _gaq || []) が評価されると、エラーがスローされます。
この場合に何が起こっているかを順を追って説明します。
代入演算子は、仕様のセクション 11.13.1で説明されています。
生産性AssignmentExpression : LeftHandSideExpression = AssignmentExpressionは次のように評価されます。
1.lrefを評価の結果とするLeftHandSideExpression。
2.rrefを評価の結果とするAssignmentExpression。
...
LeftHandSideExpressionは_gaq、AssignmentExpressionは_gqa || []。
そのため、変数が宣言されていないため、最初_qaqに評価され、解決できない参照が発生します。_gaqこの評価はエラーをスローしません。
その後_gqa || []、評価されます。これは であり、セクション 11.11で としてLogicalORExpression説明されています。この場合、は左側で、 はで、右側は です。
式は次のように評価されます。LogicalORExpression || LogicalANDExpressionLogicalORExpression_gaqLogicalANDExpression[]
1.lrefを評価の結果とするLogicalORExpression。
2. ましょlvalうGetValue(lref)。
...
は宣言されていないlrefため、解決できない参照になることは既にわかっています。_gaqそれでは、何をしているのか見てみましょう(セクション 8.7.1でGetValue定義されています。は に渡される値です):VGetValue
1. そうType(V)でない場合はReference、 を返しVます。
2.baseを呼び出した結果としGetBase(V)ます。
3. の場合IsUnresolvableReference(V)、ReferenceError例外をスローします。
...
ご覧のとおりReferenceError、このプロシージャの 3 番目のステップでエラーがスローされ、代入の右辺を評価することによって実行されます。ここでエラーがスローされます。
では、なぜこれが起こらないのvar _gaq = _gaq || [];ですか?
この行:
var _gaq = _gaq || [];
実際には
var _gaq;
_gaq = _gaq || [];
巻き上げと呼ばれるもののため[MDN] . つまり、_gaqが評価されると、解決できない参照にはならず、値を持つ参照になります。undefined
(変数_gaqが既に宣言されている (そして潜在的に値を持っている) 場合、var _gaq効果はありません。)
_gaq関数内からグローバルに作成する場合は、次を参照して明示的windowに行います。
window._gaq = window._gaq || [];