Модули позволяют структурировать большие программы, разделяя код по разным файлам и пространствам имён. Если обеспечить их хорошо разработанными интерфейсами, их будет просто использовать, применять в других проектах и продолжать использовать при развитии и эволюции самого проекта.
Хотя JavaScript совершенно не помогает делать модули, его гибкие функции и объекты позволяют сделать достаточно неплохую систему модулей. Область видимости функций используется как внутреннее пространство имён модуля, а объекты используются для хранения наборов переменных.
Есть два популярных подхода к использованию модулей. Один – CommonJS Modules, построенный на функции >require
, которая вызывает модули по имени и возвращает их интерфейс. Другой – AMD, использующий функцию >define
, принимающую массив имён модулей и, после их загрузки, исполняющую функцию, аргументами которой являются их интерфейсы.
Напишите простой модуль типа >weekday
, преобразующий номера месяцев (начиная с нуля) в названия и обратно. Выделите ему собственное пространство имён, так как ему потребуется внутренний массив с названиями месяцев, и используйте чистый JavaScript, без системы загрузки модулей.
>// Ваш код
>console.log(month.name(2));
>// → March
>console.log(month.number("November"));
>// → 10
Вернёмся к электронной жизни
Надеюсь, что глава 7 ещё не стёрлась из вашей памяти. Вернитесь к разработанной там системе и предложите способ разделения кода на модули. Чтобы освежить вам память – вот список функций и типов, по порядку появления:
>Vector
>Grid
>directions
>directionNames
>randomElement
>BouncingCritter
>elementFromChar
>World
>charFromElement
>Wall
>View
>WallFollower
>dirPlus
>LifelikeWorld
>Plant
>PlantEater
>SmartPlantEater
>Tiger
Не надо создавать слишком много модулей. Книга, в которой на каждой странице была бы новая глава, действовала бы вам на нервы (хотя бы потому, что всё место съедали бы заголовки). Не нужно делать десять файлов для одного мелкого проекта. Рассчитывайте на 3-5 модулей.
Некоторые функции можно сделать внутренними, недоступными из других модулей. Правильного варианта здесь не существует. Организация модулей – вопрос вкуса.
Запутанная тема в управлении зависимостями – круговые зависимости, когда модуль А зависит от Б, а Б зависит от А. Многие системы модулей это просто запрещают. Модули CommonJS допускают ограниченный вариант: это работает, пока модули не заменяют объект >exports
, существующий по-умолчанию, другим значением, и начинают использовать интерфейсы друг друга только после окончания загрузки.