2015-04-11 15 views
9

Wiersze 1-2 i 4-5 mają sens w odniesieniu do zwracanej wartości this. Czego mi brakuje w linii 3? Myślałem, że zwróci window podobny do linii 4-5. Czy w tych 5 nie ma innej wzmianki, która mogłaby wyjaśnić, dlaczego?Funkcje obiektów JavaScript i "ten", gdy są niezwiązane i zwracane w wyrażeniu/parens

foo = { bar : function() { return this } } 

foo.bar() // ==> foo 

(foo.bar)() // ==> foo/but why? 

(foo.bar ? foo.bar : $.noop)() // ==> window 

(foo.bar || 0)() // ==> window 
+1

Jak rozumiem, między '(foo.bar) i' foo.bar' (linia 2) nie ma różnicy. Wstawianie niepotrzebnych nawiasów, takich jak '1 + 2 * 3 ', jest takie samo, jak' 1 + (2 * 3) ' –

Odpowiedz

8

operator Ugrupowanie nie niszczy odniesień własności, które są prowokując metody połączenia.

ten jest wyraźnie wymieniony w the spec:

UWAGA: Algorytm ten nie ma zastosowania GetValue do wyniku oceny Expression. Główną motywacją jest to, że operatory , takie jak delete i typeof mogą być stosowane do nawiasowanych wyrażeń .

W swoich liniach 4 i 5, nie jest to jednak operatorzy nawias (?: i ||), które de referencyjne właściwość i dają funkcję „niezwiązany”.

+1

Dobra odpowiedź, tak naprawdę istnieją zwykłe sztuczki, aby" obejść "to, najczęstsze, jakie widziałem, to '(0, foo.bar)', aby przerwać odwołanie lub wywołać połączenie pośrednie bez dodawania linii. Daje również podstawę do [interesującego przykładu z 'eval'] (http://stackoverflow.com/questions/19357978/indirect-eval-call-in-strict-mode) :) –

3

foo.bar tutaj jest anonimowa funkcja.

Może to więcej sensu, jeśli podzielić ją na różnych liniach:

foo = { 
    bar: function() { 
     return this; 
    } 
} 

Więc, kiedy zadzwonić foo.bar, dostajesz function() { return this; }. W linii drugiej wywołuje się tę funkcję bezpośrednio (foo.bar()), więc zwraca ona this, instancję obiektu (foo).

W linii trzech, można uzyskać ten sam wynik, ponieważ nie jesteś tylko prośbą o funkcji anonimowej, ale wykonywanie tej funkcji, a także:

(foo.bar); // (function() { return this; }); A reference to the function 
(foo.bar)(); // (function() { return this; })(); Actually calling the function 

Ponieważ w tym ostatnim przypadku, jesteś wykonując funkcję tak jak w linii drugiej, wynik jest taki sam (foo).

W wierszach czwartym i piątym jednak, jak powiedział Bergi, operatory, których używasz, usuwają je z funkcji, która pozostawia ci obiekt Window, a nie foo.