2012-10-02 7 views
28

Powiel możliwe:
How do JavaScript closures work?Jaki jest cel przekazywania w ten sposób argumentów do anonimowych funkcji?

Grałem około z Google Closure Compiler, wprowadzenie kodu losowego, aby zobaczyć, co by to zrobić.

on przepisał jedną z moich funkcji wyglądać mniej więcej tak:

(function(msg) { console.log(msg); })("Hello World!");​​​​​​​ 

przypadku gdy okazuje się, że "Hello World" jest argument przekazany jako msg do anonimowej funkcji poprzedzającym go. Byłem patrząc na nią przez chwilę, a myślałem, że widziałem coś podobnego w wtyczek jQuery, które wyglądają mniej więcej tak:

(function($) { 
    ... 
})(jQuery); 

Która teraz ma większy sens dla mnie, w zakresie konfliktów z $. Ale jaki jest główny powód lub cel przekazywania argumentów w anonimową funkcję taką jak ta? Dlaczego po prostu nie zdefiniowałbyś argumentów jako zmiennych w funkcji? Czy istnieje jakaś wydajność lub elastyczność przy pisaniu takich funkcji?

+0

Dla tego konkretnego kodu nie ma prawdziwego powodu. Możesz po prostu zrobić 'console.log (" hello ");'. Zazwyczaj jednak tworzy się pewne zmienne lokalne, które są dostępne tylko dla niektórych funkcji, które są tworzone wewnątrz i eksportowane. –

+0

Chciałbym zobaczyć Twój oryginalny kod, który doprowadził do tego formularza. Założę się, że gdyby włączono opcję ADVANCED_OPTIMIZATIONS, całkowicie pozbyłbym się tej funkcji. –

+0

@ user1689607 funkcja była nieco inna i znacznie dłuższa.Zrobiłem to krótko, aby zrobić to na SO. Więcej zastanawiam się nad tym pojęciem niż ten konkretny przykład. –

Odpowiedz

10

Jest jedna istotna różnica związana również z zakresem. Poniższy kod:

(function(msg) { console.log(msg); })("Hello World!");​​​​​​​ 

jest w pewnych okolicznościach czystszych pod względem zanieczyszczenia przestrzeni nazw niż to:

var msg = "Hello World!"; 
console.log(msg); 

ponieważ drugi kod pozostawia zmienną po to nie jest już potrzebna, ale może kolidować z innymi częściami kodu.

Jest to szczególnie ważne, gdy wykonasz powyższy kod poza jakąkolwiek inną funkcją: w takim przypadku zmienna będzie dostępna wszędzie na stronie, jako zmienna globalna.

+0

Ale jak to by było inaczej niż owijanie twojego drugiego przykładu w anonimową funkcję? zmienna wciąż ginęłaby pod koniec –

+0

Byłem pod wrażeniem, że miał na myśli coś podobnego do tego: http://jsfiddle.net/cv5Jp/ –

+0

@KevinB No dobra, jaka jest różnica między twoim skrzypkiem a funkcją, którą napisałem? –

0

Zasadniczo, zawsze dobrze jest zachować kod zawinięty w ten: (function(){/*code*/}());, aby uniemożliwić kolizje twoich wrogów z innymi osobami.

Myślę, że głównym kompilatorem zamykania jest zapisanie 5 znaków: var  i =.

0

To zależy trochę od kontekstu. Istnieją pewne warunki, w których kompilator nie będzie próbował wstawiać żadnej funkcji (jeśli na przykład funkcja skalowania zawiera "eval"). Jeśli jest to zasięg globalny i uruchomiony jest tryb ADVANCED, po prostu kompilator przestał próbować wstawiać funkcje (lub wystąpił błąd w kodzie inliningowym i stracił możliwość). Jeśli uruchomisz próbkę za pomocą kompilatora w trybie ADVANCED, otrzymasz:

console.log("Hello World!");