2013-09-05 23 views
6

Do czego służy to podejście? Na przykład, z API Google OAuth:Cel (0, obj.method) (param1, param2) w minilimencie kompilacji zamknięć

(0, _.Q)("gapi.auth.authorize", _.Ek.Ff); 
(0, _.Q)("gapi.auth.checkSessionState", _.Ek.MH); 
(0, _.Q)("gapi.auth.getAuthHeaderValueForFirstParty", _.Ek.Qe); 
(0, _.Q)("gapi.auth.getToken", _.Ek.$f); 
(0, _.Q)("gapi.auth.getVersionInfo", _.Ek.Wk); 
(0, _.Q)("gapi.auth.init", _.Ek.gb); 
(0, _.Q)("gapi.auth.setToken", _.Ek.Ym); 

do mnie, to wydaje się być identyczna po prostu wyprowadzania

_.Q("gapi.auth.authorize", _.Ek.Ff); 
_.Q("gapi.auth.checkSessionState", _Ek.MH); 
... 

Jestem zakładając, że nie jest. więc jaka jest różnica?

+0

Kompilator zmusza drugi argument do operatora przecinka do interpretacji jako wyrażenie. Jeśli zamiast '_.Q' mamy anonimową funkcję, zostanie wywołana (zamiast rzucać błąd). Jest to jedyny powód tego, o czym mogę myśleć. – bfavaretto

+0

Czy możesz podać przykład? –

+0

Miałem na myśli '(0, function (a, b) {}) (" gapi.auth.authorize ", _.Ek.Ff)' jest w porządku, ale 'function (a, b) {} (" gapi.auth .authorize ", _.Ek.Ff)' nie jest (błąd składniowy). Kompilator może więc dodawać, że to bezpieczne, zależy od tego, co dzieje się po zera. W każdym razie zero nie byłoby konieczne, więc teraz mam inne przypuszczenie: może kompilator może wstawić 'eval' zamiast' _.Q'; w tym przypadku '(0, eval)' wymusiłoby pośrednie wywołanie eval (lub "global eval"). Zobacz http://stackoverflow.com/questions/9107240/1-evalthis-vs-evalthis-in-javascript. – bfavaretto

Odpowiedz

5

Kompilator jest upewniając się, że „to” wartość jest poprawna:

a.f() // 'this' value is "a" 
(0, a.f)() // 'this' is the default "this" value 

Powodem widać to w API OAuth jest kod za pomocą „rescope globalne symbole” kompilatora przepustkę. Ta przepustka umieszcza symbole, które w innym przypadku zostałyby wprowadzone w globalnym zasięgu, aby komunikować się na zakresach funkcji (IIFE) na obiekcie. Więc kod tak:

function f(); 

// some potentially late loaded code 
f(); 

staje:

Ale tutaj "f" 's 'to' wartość zmieniła się od domyślnego 'to' z "_". Aby zapobiec tej zmianie, zamiast niej jest używany "(0, _.f)()".

Jest to obszar, w którym kompilator może ulec poprawie, ponieważ robi to nawet w przypadkach, w których może stwierdzić, że "ten" nie jest używany w ciele funkcji.