Должен ли я вкладывать функции в языки, которые позволяют мне это делать, или мне лучше этого избегать?


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 нет области видимости модуля, поэтому вам нужно анонимное закрытие.
Raynos

И если этот щелчок выполняет Ajax-вызов с обратным вызовом завершения? Теперь у вас есть функции, вложенные в два уровня. Конечно, вы можете ограничить вложение, назначив анонимные замыкания переменным. Это действительно лучше?
Кевин Клайн

2

Это один из тех вопросов, на которые нет правильного ответа, и на ум приходят такие слова, как «личные предпочтения», «командная практика». По моему мнению, маленькие функции (теперь это еще одна субъективная вещь), которые нигде не используются, принадлежат их родительским функциям, особенно когда они могут быть безымянными.


0

На этот вопрос нет правильного ответа, потому что ни один из вариантов не максимизирует инкапсуляцию. Если вы вложите их, у них все еще есть доступ к переменным, которые они не должны иметь. Если нет, то другие функции имеют доступ к функциям, которых они не должны иметь. В любом случае, вы проиграли.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.