Общие принятые лучшие практики организации кода в JavaScript [закрыт]
Проблема: Как организовать код JavaScript в больших проектам?
С тех пор как JavaScript-фреймворки, такие как jQuery, сделали клиентские веб-приложения более функциональными и насыщенными, я начал замечать одну проблему...
Как же, черт возьми, удержать это в порядке?
- Поместить все обработчики в одно место и написать функции для всех событий?
- Создать функции или классы для обертки всей вашей функциональности?
- Писать код, как сумасшедший, и надеяться, что в итоге все сработает?
- Сдаться и сменить карьеру?
Я упоминаю jQuery, но на самом деле это касается любого кода JavaScript в общем. Я понимаю, что по мере увеличения строк кода становится все сложнее управлять файлами сценариев и находить нужные фрагменты. Возможно, самой большой проблемой является то, что существует множество способов достижения одной и той же цели, и сложно понять, какой из них является общепринятой лучшей практикой.
Существуют ли какие-либо общие рекомендации по тому, как лучше организовать ваши .js файлы так же аккуратно и чисто, как и остальная часть вашего приложения? Или это просто вопрос выбора IDE? Есть ли что-то лучшее?
Редактирование
Этот вопрос был направлен больше на организацию кода, а не на организацию файлов. Здесь были приведены хорошие примеры объединения файлов или разбиения контента.
Меня интересует: какова сейчас общепринятая лучшая практика по организации самого кода? Как вы организуете свой код, или есть ли рекомендованный способ взаимодействия с элементами страницы и создания переиспользуемого кода, который не конфликтует друг с другом?
Некоторые предложили неймспейсы, что является хорошей идеей. Какие еще способы существуют, особенно касающиеся работы с элементами на странице и поддержания кода в порядке?
5 ответ(ов)
Я стараюсь избегать включения JavaScript непосредственно в HTML. Весь код инкапсулируется в классы, и каждый класс находится в своем собственном файле. Для разработки у меня есть отдельные теги <script>
, включающие каждый файл JS, но они объединяются в один более крупный пакет для продакшна, чтобы сократить количество HTTP-запросов.
Обычно у меня есть один "основной" файл JS для каждого приложения. Например, если я пишу приложение "опрос", у меня будет файл JS с именем "survey.js". В этом файле содержится точка входа в код jQuery. Я создаю ссылки на jQuery во время инстанцирования, а затем передаю их в свои объекты в качестве параметров. Это означает, что классы JavaScript 'чистые' и не содержат ссылок на CSS ID или классы.
// файл: survey.js
$(document).ready(function() {
var jS = $('#surveycontainer');
var jB = $('#dimscreencontainer');
var d = new DimScreen({container: jB});
var s = new Survey({container: jS, DimScreen: d});
s.show();
});
Я также считаю, что соглашение о наименовании важно для читаемости. Например, я ставлю префикс 'j' ко всем экземплярам jQuery.
В приведенном выше примере есть класс под названием DimScreen (предположим, он затеняет экран и вызывает всплывающее окно). Ему нужен элемент div, который он может увеличить, чтобы закрыть экран, а затем добавить всплывающее окно, поэтому я передаю ему объект jQuery. jQuery имеет концепцию плагина, но она кажется ограниченной (например, экземпляры не являются постоянными и не могут быть доступны) без реальной выгоды. Поэтому класс DimScreen будет стандартным классом JavaScript, который просто использует jQuery.
// файл: dimscreen.js
function DimScreen(opts) {
this.jB = opts.container;
// ...
}; // не забудьте точку с запятой для минификации!
DimScreen.prototype.draw = function(msg) {
var me = this;
me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
//...
};
Я создал несколько довольно сложных приложений, используя этот подход.
Организация кода требует принятия соглашений и стандартов документации. Вот некоторые рекомендации, которые помогут вам структурировать ваш код:
- Создайте пространство имен для файла:
Exc = {};
Группируйте классы в пространствах имен: Это позволит вам поддерживать порядок и избегать конфликтов имен.
Устанавливайте прототипы или связанные функции/классы для представления объектов реального мира:
Exc = {};
Exc.ui = {};
Exc.ui.maskedInput = function (mask) {
this.mask = mask;
// дополнительные методы и свойства
};
Exc.ui.domTips = function (dom, tips) {
this.dom = dom;
this.tips = tips;
// дополнительные методы и свойства
};
- Установите соглашения для улучшения кода. Например, группируйте все внутренние функции или методы в атрибуте класса объекта:
Exc.ui.domTips = function (dom, tips) {
this.dom = dom;
this.tips = tips;
this.internal = {
widthEstimates: function (tips) {
// логика
},
formatTips: function () {
// логика
}
};
// дополнительные методы и свойства
};
- Документируйте пространства имен, классы, методы и переменные. При необходимости также комментируйте важные части кода (например, циклы и условия), которые реализуют ключевую логику.
/**
* Пространство имен <i> Example </i> создано для группировки других пространств имен "Example".
*/
Exc = {};
/**
* Пространство имен <i> ui </i> создано для группировки пространств имен пользовательского интерфейса.
*/
Exc.ui = {};
/**
* Класс <i> maskdInput </i> используется для добавления возможностей форматирования ввода HTML и валидации данных.
* @param {String} mask - маска для валидации вводимых данных.
*/
Exc.ui.maskedInput = function (mask) {
this.mask = mask;
// дополнительные методы и свойства
};
/**
* Класс <i> domTips </i> используется для добавления элементам HTML возможности отображения подсказок и информации о их функции.
* @param {String} id - идентификатор HTML элемента.
* @param {String} tips - подсказки, которые появятся при наведении мыши на элемент с идентификатором id.
*/
Exc.ui.domTips = function (id, tips) {
this.domID = id;
this.tips = tips;
// дополнительные методы и свойства
};
Эти советы значительно помогут в организации вашего кода. Не забывайте, что для достижения успеха необходима дисциплина!
Если ваш начальник всё ещё вспоминает времена, когда писали модульный код на C, и жалуется на качество современного кода, это может быть отражением проблемы, с которой сталкиваются многие разработчики. Да, действительно, программисты могут писать на ассемблере в любом фреймворке, и всегда есть хорошие стратегии для организации кода. Основная проблема заключается в тех, кто рассматривает JavaScript как игрушку и не пытается вникнуть в его особенности.
В вашем случае, вы уже применяете правильный подход — структурируете JS-файлы по темам интерфейса пользователя или экранам приложения и используете соответствующую функцию init_screen()
. Придерживаясь правильной конвенции именования идентификаторов, вы предотвращаете конфликты пространств имён на уровне корневого элемента. Таким образом, связывание элементов на уровне window.onload
происходит корректно.
Использование замыканий и паттернов для скрытия приватных методов — это тоже очень хорошая практика. Она действительно помогает избежать конфликтов свойств, функций и определений переменных. Однако, как вы справедливо заметили, в команде может возникнуть сложность с тем, чтобы все придерживались одного и того же строгого подхода. Это требует активного общения и согласования стандартов кодирования внутри команды, чтобы обеспечить хорошую организацию кода и избежать потенциальных проблем.
Похоже, вы сталкиваетесь с классической проблемой, когда разработка становится неуправляемой. Фраза "Пишите как можете, и просто надейтесь на лучшее" может работать на начальных этапах, но в долгосрочной перспективе это приведет к хаосу, особенно в большом проекте с большим объемом JavaScript-кода.
Я полностью согласен с вашим мнением о jQuery. Хотя он может быть удобен для быстрого прототипирования, использование его на крупных проектах действительно может привести к нежелательной запутанности. Часто разработчики начинают использовать сокращения для каждого метода jQuery, что в итоге приводит к тому, что код становится сложным для понимания и поддержки. Ваше предложение организовать код в виде плагинов – это хороший шаг, так как это приближает структуру к объектно-ориентированному подходу, но проблема в том, что это требует дисциплины и понимания.
Относительно организации JavaScript-кода: использование пространства имен и классов действительно может упростить структуру вашего проекта. Как вы упомянули, такие фреймворки, как YUI и Dojo, предоставляют удобные инструменты для структурирования кода. Если вам нужно писать чистый и поддерживаемый код без jQuery, вы можете рассмотреть варианты работы с ES6+ модулями и классами. Это позволит вам избежать избыточности и улучшить читаемость кода.
Так что в общем, да, лучше организовывать код с самого начала, чем потом пытаться его реорганизовать, когда проект наберет критическую массу сложности. Удачи вам в ваших усилиях!
На русском это может звучать так:
Я создаю синглетоны для всего, что не требует многократной инстанциации на экране, а для всего остального использую классы. Все они находятся в одном пространстве имен и в одном файле. Код хорошо прокомментирован и спроектирован с использованием UML и диаграмм состояния. JavaScript код свободен от HTML, то есть я избегаю inline JavaScript, и предпочитаю использовать jQuery, чтобы минимизировать проблемы с кроссбраузерной совместимостью.
Как перенаправить на другую веб-страницу?
Прокрутка к элементу с использованием jQuery
Как определить нажатие клавиши Esc?
Удалить ВСЕ пробелы из текста
Как получить данные формы с помощью JavaScript/jQuery?