Чи варто вкладати функції мовами, які дозволяють мені це робити, або я краще уникати цього?


12

У JavaScript, PL / SQL та деяких інших мовах функції можуть бути вкладені, тобто оголошені в іншій функції. Це можна використати для розбиття великої функції на більш дрібні частини, але зберегти ці частини в контексті більшої функції.

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

    // doTooMuch body

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

У деяких випадках, коли ті менші функції не використовують локальні змінні більшої функції, це може бути легко змінено на версію, де всі функції не мають функції.

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

Якщо припустити, що ці вкладені функції не використовуватимуться більше ніде, чи краще зберігати їх у контексті великої функції чи це погано, оскільки саме це робить велику функцію ну ну великою?

Відповіді:


8

Це питання думки, але я б уникав функцій гніздування, якщо це насправді не була необхідною і обдуманою частиною вашого дизайну.

Коли ви вкладаєте функції в більшості мов, у вас виникає якийсь механічний ефект. Найпоширенішим і цікавим є закриття лексичної сфери змінної, яка може використовуватися всередині тіла, але інші (наприклад: видимість функції) також з'являються частину часу.

Це, як правило, дивовижні інструменти при правильному використанні, але вони є складними інструментами, оскільки вони можуть спричинити не локальні або неочевидні ефекти при першому погляді на код.

Якщо ви не користуєтесь ними, багато людей прочитають код і не побачать нічого цього - тому припустять, що вони його пропустили, і переглянуть ще раз, намагаючись розібратися, чому ви це зробили саме так, а не в окремому обсязі.

Ви також ризикуєте, що майбутні програмісти навмисно чи навіть випадково закриють щось, чого не мали наміру, не помічаючи ризику саме там.

Нарешті, якщо ваша декларація функції оголошує іменовану функцію поза межами функції, що додається, просто уникайте її. Це дуже заплутано для всіх.

Що стосується останнього зауваження: оскільки окремі функції допомагають розмежувати код, гніздові функції менш клопітно , ніж однієї гігантської функції, але в кінцевому рахунку це робить середній читання набагато більше коду , щоб зрозуміти doTooMuch()- особливо якщо ви можете приховати код між вкладеними оголошення функцій, або потрібно перевірити, що ніхто не робив.


-1: JavaScript не є "більшості мов". Функції введення в Javascript - це звичайна практика.
кевін клайн

2
@kevincline вкладені функції в JavaScript є звичайною поганою практикою
Raynos

@Raynos: Якщо ви не гніздите їх, куди їх збираєтесь поставити? У вас немає класів, щоб їх містити. Ось декілька типових кодів:jquery(function($){ $('#id').click(function(){...}); }
Кевін Клайн

@kevincline ... Типовий код для noobs, вам потрібні функції, вкладені одна глибока. І це тому, що JavaScript не має модульної області, тому вам потрібно це анонімне закриття.
Райнос

І якщо цей клік виконує дзвінок Ajax, із зворотним викликом завершення? Тепер у вас є функції, вкладені у два рівні. Звичайно, ви можете обмежити вкладення, призначивши анонімні закриття змінним. Це справді краще?
кевін клайн

2

Це одне з тих питань, на які немає правильної відповіді і на думку приходять такі слова, як "особисті переваги", "командна практика". На мою думку, маленькі функції (зараз це ще одна суб’єктивна річ), які ніде не використовуються, належать до їхніх батьківських функцій, особливо коли вони можуть бути без назви.


0

На це питання немає правильної відповіді, оскільки жоден вибір не забезпечує максимальну інкапсуляцію. Якщо ви вкладете їх, вони все ще мають доступ до змінних, які вони не повинні. Якщо цього немає, то інші функції мають доступ до функцій, які вони не повинні. У будь-якому випадку ви програєте.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.