2013-03-11 7 views
7

Google Analytics początkowo używa numeru _gaq[object Array]. Przekazywanie tablicy do funkcji odbywa się w JavaScript, przechodząc przez obiekt, a więc przez odwołanie.Dlaczego zmiany prototypów nie są przekazywane przez odwołanie do metody?

(Edit: Jak wskazano w odpowiedzi, odwołanie jest przekazywane przez wartość Zobacz https://stackoverflow.com/a/5314911/120521 więcej szczegółów na temat odniesienia/wartość przechodzącej w JavaScript.). Poniżej

Kod wykorzystuje jQuery czekać DOM załadować, a następnie dołączyć wydarzenie change, które wyśle ​​wirtualną odsłonę do Google Analytics po zmianie przez użytkownika pola <input/>.

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 

Jednakże, jak to widać w komentarzu powyżej, sposób trackInputs() drukuje „pierwotnym” tablicę. Zazwyczaj skrypt Google Analytics zmienia tablicę _gaq w obiekt _gaq i zmienia prototyp wypychania obiektu, aby po wywołaniu nowego wywołania kierował on żądania do serwerów Google Analytics.

Dlaczego ta zmiana nie została również przekazana przez odniesienie do trackInputs()?

Zdaję sobie sprawę załadowany skrypt Google Analytics (lub będzie?) Występują po definicji Tracking.trackInputs(), więc przeglądarka może nie zrozumieć, to jest teraz [object object] ale utrzymują się myśląc, że to oryginalny [object Array]. Ale to już nie jest odniesienie, prawda?

(Używanie obiektu _gaq globalnie (nie przekazując je do sposobu w ogóle) będzie rozwiązać ten problem, ale chcę, aby zrozumieć, dlaczego to nie działa.)

Odpowiedz

3

Google Analytics początkowo korzysta z _gaq [object Array]. Przekazywanie tablicy do funkcji odbywa się w JavaScript, przekazując obiekt, a więc przez odniesienie .

Wstępne założenie jest nieprawidłowe. JavaScript zawsze używaj przekazywania według wartości. Przekaż według wartości. PRZEJDŹ NA WARTOŚĆ.

podajesz odwołanie do obiektu według wartości. Numer referencyjny jest przekazywany WARTOŚĆ. Na koniec dnia masz wiele odniesień do samej podstawowej tablicy, ponieważ za każdym razem, gdy odwołanie jest przekazywane przez wartość, masz nową kopię odwołania, ale obiekt nigdy się nie zmienia.

Zwykle co skrypt Google Analytics robi to zmienia tablicę _gaq do obiektu _gaq i zmienia prototyp dążyć do obiektu, aby to uczynić żądań do serwerów Google Analytics raz nowe połączenie jest przekazywane do obiekt.

Gdzie to robi?

Jednakże, jak to widać w komentarzu powyżej, sposób trackInputs() odciski „pierwotnym” tablicy.

Oczywiście, że tak.

var _gaq = _gaq || []; 
_gaq.push(['_setAccount', _gAAccount]); 
_gaq.push(['_trackPageview']); 

zdefiniować i rozmieścić w nim elementy.

jQuery(document).ready(function($) { 
    Tracking.trackInputs($, _gaq); 
}); 

podał, że matryca o wartość do metody

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

tworzyć zamknięcie wokół gaObject, który nawiązuje do oryginalnej tablicy i użyć go do obsługi wymiany. To nie jest to samo odniesienie, co _gaq, kopia tego odwołania, ale wskazuje na tę samą tablicę.

+1

-1 pojawia się problem semantyczny, ale nie próbujesz rozwiązać pytania –

+0

Jeśli powiem, że "silnik samochodu działa poprzez fuzję jądrową, ale nie rozumiem, jak to działa, gdy wkładam gaz do samochodu", a ty odpowiedź "samochody nie działają na fuzję jądrową", czy naprawdę nie ma powodu, aby odpowiedzieć na drugą część pytania? – hvgotcodes

+0

"Gdzie to robi?" - w ga.js – joakimdahlstrom

0

Na ryzyko mówiąc coś głupiego jak Wpatrywałam się w twój skrypt przez około 20 minut i nic oczywistego się na mnie nie wyskakuje ... Czy to w ogóle możliwe, że działa zgodnie z założeniami, jednak twoje teczki testowe są pomijane w Analytics, ponieważ Twój własny adres IP jest na liście pod profile filters?

+0

Haha, kocham „? Czy sprawdzić masz moc” sprawdzenie stanu psychicznego. Tak, odprawiłem to. Łatwo jest sprawdzić aktywność sieciową i szukać żądań dla __utm.gif. –

+0

@DavidAndersson Wystarczająco fair - jestem trochę zaskoczony - nigdy nie musiałem naciskać kodu śledzenia poza domyślną konfigurację. To, co mnie myli, to to, że w dev. konsoli na mojej własnej stronie robię 'console.log (_gaq)' - otrzymuję tablicę tablic takich, jakie wymieniono w twoich komentarzach. Ale jeśli zrobię to samo na stackoverflow na przykład dostaję obiekt i nie mogę zauważyć różnicy w jaki sposób stackoverflow ładuje ga.js? – Emissary

+0

Nie jestem nawet pewien, czy to jest istotne, czy pomocne - po prostu obserwacja. – Emissary

5
jQuery(document).ready(function($) { 
    Tracking.trackInputs($, _gaq); 
}); 

Ponieważ DOM gotowy przed GA załadowaniu odniesienia _gaq nadal wskazuje zwykłej macierzy, która jest następnie utrwalona przez lokalną symbolu gaObject wewnątrz funkcji trackInputs().

trackInputs: function ($, gaObject) { 

GA Po załadowaniu, światowy symbol _gaq otrzymuje trackera, ale gaObject nadal wskazuje na starym symbolem.

Można użyć „Ready” cechę GA zadzwonić czynność trackInputs() zamiast korzystania $(document).ready(...):

_gaq.push(function() { 
    // when this runs, the tracker would have initialized; 
    Tracking.trackInputs($, _gaq); 
}); 
+0

I domyślam się, że to, co próbujesz powiedzieć, to utrata odniesienia, gdy ga.js _replaces_ kompletną zawartość obiektu, prawda? Ponieważ, jeśli naciskasz tylko nowe wartości (lub modyfikujesz istniejące klucze) do obiektu w nim, zmodyfikujesz oryginalny obiekt. – joakimdahlstrom

+0

@joakimdahlstrom well, odniesienie jest przechowywane w 'gaObject' wewnątrz funkcji' trackInputs' :) –

+0

No tak. Ale myślę, że trackInputs odwoła się do niewłaściwego obiektu podczas zastępowania pełnej treści obiektu. Dobrze? – joakimdahlstrom

0
jQuery(document).ready(function() { 
    _gaq.push(function() { 
    Tracking.trackInputs($, _gaq); 
    }); 
}); 
Powiązane problemy