Страницы

Поиск по вопросам

понедельник, 15 октября 2018 г.

JavaScript: стоит ли избегать стиля написания кода “функция в функции”?

Допустим, у нас есть JavaScript приложение с большим количеством виджетов. Рассмотрим на примере шапки. Функция initHeader() собирает все нужные для дальнейшей работы DOM-объекты внутри шапки, добавляет обработчики событий, вообщем готовит к её использованию. Соответствует ли приведённый ниже шаблон кода "правилам хорошего тона" написания кода?
function initHeader(){
// объекты виджета, с которыми будем работать в функциях var var1 = $('#div1'); var var2 = $('#div2'); // ...
// вспомогательные функции
function function1(){ // ... }
function function2(){ // ... }
function function3(){ // ... } }
Особенность этого шаблона в том, что все вспомогательные функции находятся внутри основной.
Зачем такая структура? Согласно книге Роберта Мартина "Чистый код", в идеале у функции не должно быть аргументов вообще, а если аргументы неизбежны, то должен быть один, максимум два аргумента. Но в нашем случае, внутри вспомогательных функций может быть нужно большое количество переменных: jQuery-объекты, какие-то константы, рабочие переменные наподобие времени анимации, какие-то введённые данные и так далее. Если написать все вспомогательные функции вне основной, то тогда придётся всё это передавать в виде аргументов, и в два аргумента уложиться едва ли получится. Такая структура, которую я показал, избавляет нас от необходимости передавать аргументы, при этом все переменные, будучи объявленными внутри initHeader(), за пределами данной функции недоступны.
Второй плюс данного подхода в том, что он позволяет единыжды собрать все DOM-объекты через функцию jQeury(), а потом уже обращаться к ним через имена переменных (если это корректно называть кэшированием DOM-элементов, то можно сказать, что данный шаблон кода создаёт условия для обеспечения кэширования DOM-элементов).
И ещё: это следует из названия функции, но всё же уточню, что сама функция initHeader() вызывается только один раз (это можно сделать в HTML-коде сразу после закрывающего , например), а внутренние функции уже могут быть вызваны сколько угодно раз.
Приведите, пожалуйста, аргументы за и/или против такого подхода.


Ответ

В Javascript этот стиль используется для ограничения области видимости вложенных таким образом функций, с целью предоставлять только необходимые внешние интерфейсы (с аналогичной целью, как приватные методы в C++). См. например, паттерн модуль, фасад. Таким образом, ничего плохого тут не сделано, только в исходном примере паттерн недоразвит.
Замечу, что нет необходимости добавлять собранные скрипты в header, лучше это сделать в конце body, чтобы на момент их загрузки все элементы разметки уже были обработаны.
А условие загрузки определённой части кода (модуля) должно быть независимо от факта старта скрипта, управляться специальной сущностью - например инициализацией виджета или роутингом.
Что касается упомянутой в вопросе рекомендации использовать один или менее аргументов у функции - надо понимать, что в контексте Javascript это просто забавно звучит и, вероятно, должно пониматься как-то иначе. Всё-таки, это мультипарадигменный, в т.ч. функциональный, язык программирования. Т.е. да, конечно, вместо множества аргументов лучше использовать каррированные функции и их композиции. Далее, с озвученной в вопросе целью, передаётся один аргумент - объект, что, вместе с сахаром ES6-деструктуризации и той или иной системой проверки типов, даёт самые гибкие средства для передачи групп сущностей в/из функции.

Комментариев нет:

Отправить комментарий