Czy powinienem zagnieżdżać funkcje w językach, które mi na to pozwalają, czy raczej powinienem tego unikać?

12

W JavaScript, PL / SQL i niektórych innych językach funkcje mogą być zagnieżdżone, tzn. Zadeklarowane w innej funkcji. Można to wykorzystać do podzielenia dużej funkcji na mniejsze części, ale zachowaj je w kontekście większej funkcji.

function doTooMuch() {
    function doSomething () {
       ...
    }
    function doSomethingElse() {
       ...
    }
    function doYetAnotherThing() {
       ...
    }

    // doTooMuch body

    doSomething();
    doSomethingElse();
    doYetAnotherThing();
}

W niektórych przypadkach, gdy te mniejsze funkcje nie używają zmiennych lokalnych większej funkcji, można to łatwo zmienić na wersję, w której wszystkie funkcje są odszyfrowane.

function doSomething () {
   ...
}
function doSomethingElse() {
   ...
}
function doYetAnotherThing() {
   ...
}
function doTooMuch() {
    doSomething();
    doSomethingElse();
    doYetAnotherThing();
}

Zakładając, że tych zagnieżdżonych funkcji nie można używać nigdzie indziej, czy lepiej jest trzymać je w kontekście dużej funkcji, czy jest to złe, ponieważ właśnie to sprawia, że ​​duża funkcja jest dobra?

użytkownik 281377
źródło

Odpowiedzi:

8

Jest to kwestia opinii, ale unikałbym zagnieżdżania funkcji, chyba że faktycznie byłaby to niezbędna i celowa część twojego projektu.

Kiedy zagnieżdżasz funkcje, w większości języków kończy się to jakimś efektem mechanicznym. Najczęstszym i najciekawszym jest zamknięcie zakresu leksykalnego zmiennej, która może być używana wewnątrz ciała, ale inne (np. Widoczność funkcji) również czasem się pojawiają.

Są to zwykle niesamowite narzędzia, gdy są właściwie używane - ale są to narzędzia złożone, ponieważ mogą powodować nielokalne lub nieoczywiste efekty, gdy spojrzysz na kod po raz pierwszy.

Jeśli ich nie użyjesz, wiele osób przeczyta kod i nie zobaczy niczego, co by to robiło - więc założymy, że go przegapili, i spójrz ponownie, próbując dowiedzieć się, dlaczego to zrobiłeś, a nie w osobnym zakresie.

Ryzykujesz również, że przyszli programiści celowo lub nawet przypadkowo zamkną coś, czego nie zamierzali, nie zauważając ryzyka w tym miejscu.

Na koniec, jeśli deklaracja funkcji deklaruje nazwaną funkcję poza zakresem funkcji zamykającej, po prostu jej unikaj. To jest bardzo mylące dla wszystkich.

Ostatnia uwaga: ponieważ poszczególne funkcje pomagają rozdzielić kod, funkcje zagnieżdżania są mniej kłopotliwe niż pojedyncza gigantyczna funkcja, ale ostatecznie oznacza to przeczytanie znacznie większej ilości kodu do zrozumienia doTooMuch()- zwłaszcza jeśli można ukryć kod między deklaracjami funkcji zagnieżdżonych lub muszę sprawdzić, czy nikt tego nie zrobił.

Daniel Pittman
źródło
-1: Javascript nie jest „większością języków”. Zagnieżdżanie funkcji w JavaScript jest normalną praktyką.
kevin cline
2
Funkcje zagnieżdżania @kevincline w JavaScript są powszechną złą praktyką
Raynos
@Raynos: Jeśli ich nie zagnieżdżycie, gdzie je zamierzacie umieścić? Nie ma żadnych klas, które mogłyby je zawierać. Oto typowy kod:jquery(function($){ $('#id').click(function(){...}); }
Kevin Cline
@kevincline ... Typowy kod dla noobów, potrzebujesz funkcji zagnieżdżonych głęboko. A to dlatego, że javascript nie ma zasięgu modułu, więc potrzebujesz tego anonimowego zamknięcia.
Raynos
A jeśli to kliknięcie wykonuje wywołanie Ajax, z wywołaniem zwrotnym zakończenia? Teraz masz funkcje zagnieżdżone na dwóch poziomach. Jasne, możesz ograniczyć zagnieżdżanie, przypisując anonimowe zamknięcia do zmiennych. Czy to naprawdę lepsze?
kevin cline
2

To jedno z tych pytań, na które nie ma właściwej odpowiedzi, i przychodzą mi na myśl słowa „osobiste preferencje”, „trening zespołowy”. Moim zdaniem małe funkcje (teraz jest to kolejna subiektywna rzecz), które nie są nigdzie używane, należą do ich funkcji nadrzędnych, zwłaszcza gdy można je nazwać bezimiennie.

devmiles.com
źródło
0

To pytanie nie ma właściwej odpowiedzi, ponieważ żaden wybór nie maksymalizuje enkapsulacji. Jeśli je zagnieżdżycie, nadal będą mieli dostęp do zmiennych, których nie powinni. Jeśli nie, to inne funkcje mają dostęp do funkcji, których nie powinny. Tak czy inaczej, przegrywasz.

DeadMG
źródło