Wszystkie funkcje JavaScript będzie zachowywać się w taki sam sposób, w który oni dziedziczą zmienne środowiska w całym łańcuchu zasięgu prowadzących do i tym sami. Dotyczy to zarówno funkcji anonimowych, jak i nazwanych.
Łańcuch odniesień do środowiska zewnętrznego zostaje ze wszystkich funkcji, nawet wtedy, gdy funkcja jest przekazywana do zupełnie innego zakresu.
Tradycyjnie, oznaczałoby to, że wszystkie zmienne w danym łańcuchu mają odniesienie zatrzymany do nich tak długo, jak wewnętrzna zamknięcie nadal istnieje. Chociaż w nowoczesnych przeglądarkach, które kompilują kod, prawdopodobne jest, że nastąpi analiza, które zmienne są faktycznie przywoływane, a tylko te będą zachowane, pozwalając innym, które nie są już przywoływane, do zbierania śmieci.
Istnieją jednak inne sytuacje, w których funkcja anonimowa jest marnotrawstwem.
Oto wspólny kawałek kodu:
for(var i = 0; i < 100; i++) {
(function(j) {
setTimeout(function() { console.log(j); }, 1000);
})(i);
}
Jest to sytuacja, w której anonimowa funkcja jest nieco bardziej rozrzutny niż nazwie funkcji, ponieważ jesteś odtworzyć identyczną funkcję 100 razy podczas pętli, kiedy może po prostu ponownie użyć nazwanego.
function setConsole(j) {
setTimeout(function() { console.log(j); }, 1000);
}
for(var i = 0; i < 100; i++) {
setConsole(i);
}
Ma to dokładnie ten sam narzut zamknięcia, ale jest bardziej wydajny, ponieważ skonstruowano tylko jedną funkcję do tworzenia każdego nowego środowiska zmiennych.
http://jsperf.com/immediate-vs-named(Dzięki @Felix Kling dla jsPerf.)
Jeśli chodzi o zamknięcie, to tak, tak, tak długo, jak utrzymujesz zamknięcie przez stałe odniesienie. Powiedziałbym, że dobrze jest tego uniknąć, jeśli to możliwe, ale nie być obsesyjnym na ten temat. Czasami nowe zmienne środowisko dodane do łańcucha zasięgu jest po prostu najlepszym rozwiązaniem.
EDIT:Here's an article from Google. W szczególności zobacz Unikanie pułapek z zamknięciami. w celu uzyskania informacji o wpływie na wydajność rozszerzenia łańcucha zasięgu oraz o twierdzeniu, że funkcje anonimowe są "wolniejsze" niż funkcje nazwane.
Doskonałe pytanie. Wykorzystałem swoje głosy na ten dzień - czy ktoś inny może dla mnie dać +1? –
@Michael Już zrobił. Świetne pytanie. –
Było podobne pytanie na SO o * implementacji * zamknięć, ale jeszcze nie widziałem jednego z satysfakcjonującą odpowiedzią. To znaczy, czy * nowoczesne * silniki JavaScript są na tyle inteligentne, aby trzymać tylko obiekty w [[scope]], które * mogą * być dostępne? Oczywiście ta optymalizacja nie jest praktyczna do zastosowania w obecności 'eval', etc ... –