JavaScript. Рецепты для разработчиков
Қосымшада ыңғайлырақҚосымшаны жүктеуге арналған QRRuStore · Samsung Galaxy Store
Huawei AppGallery · Xiaomi GetApps

автордың кітабын онлайн тегін оқу  JavaScript. Рецепты для разработчиков

 

Адам Д. Скотт , Мэтью МакДоналд, Шелли Пауэрс
JavaScript. Рецепты для разработчиков. 3-е изд
2023

Переводчики Е. Сандицкая


 

Адам Д. Скотт , Мэтью МакДоналд, Шелли Пауэрс

JavaScript. Рецепты для разработчиков. 3-е изд. — СПб.: Питер, 2023.

 

ISBN 978-5-4461-2001-7

© ООО Издательство "Питер", 2023

 

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

 

Предисловие

Садясь за работу над последним изданием книги «JavaScript. Рецепты для разработчиков», я решил, что «рецепты» — точная метафора. Что отличает хороший сборник кулинарных рецептов? Перебрав несколько кулинарных справочников, стоящих на полке в кухне, я обнаружил, что мои любимые — это те, в которых не только описаны самые вкусные блюда, но и дается много советов, основанных на богатом опыте знающих людей. Хорошая кулинарная книга — не та, где вы найдете все варианты приготовления мяса по-бургундски, а та, где описаны наилучшие, по мнению автора, методики и рецепты, к которым обычно прилагается несколько советов. Именно такой концепцией мы и решили руководствоваться, собирая коллекцию рецептов по JavaScript. Советы, представленные в этой книге, дают трое маститых профессионалов, но это кульминация главным образом нашего уникального опыта. Окажись на нашем месте другие разработчики, они бы написали похожую, но другую книгу.

JavaScript вырос в невероятный, высокоэффективный, многоцелевой язык программирования. С нашей подборкой рецептов в руках вы сможете не только решать всевозможные проблемы, которые вам встретятся, но и придумывать собственные рецепты.

Аудитория этой книги

Предупреждаем сразу: стремясь охватить все разнообразие тем и областей, в которых сегодня используется JavaScript, мы не рассчитывали на новичков в программировании. Для тех, кто начинает изучать программирование на JavaScript, есть так много хороших книг и учебных пособий, что мы со спокойной совестью посвятили свою практикующим разработчикам — тем, кто ищет решение конкретных проблем и задач на JavaScript.

Если вы успели попрактиковаться с JavaScript лишь в течение пары месяцев — возможно, попробовали силы в разработке для Node или веб-разработке, то изучение материала этой книги не должно вызвать у вас затруднений. Издание станет полезным руководством и для тех разработчиков, кто в основном имеет дело с другим языком программирования, но время от времени испытывает потребность в JavaScript. Наконец, если вы действующий разработчик на JavaScript, но вас иногда ставят в тупик некоторые особенности языка, то эта книга также станет для вас полезным ресурсом.

Структура издания

У книги есть два типа читателей. Первые — те, кто прочитает ее от корки до корки, подобрав по дороге каждую крошку полезных знаний. Вторые будут углубляться в чтение лишь по мере необходимости в поисках решения определенной задачи или категории стоящих перед ними проблем. Мы постарались структурировать книгу таким образом, чтобы она была полезной обеим категориям читателей. Для этого разбили ее на три части.

• Часть I. Язык JavaScript. Сюда вошли рецепты для JavaScript как языка программирования.

• Часть II. JavaScript в браузере. Здесь описан JavaScript в его естественной среде обитания — в браузере.

• Часть III. Node.js. Здесь JavaScript рассматривается сквозь призму Node.js.

Все главы книги разделены на несколько самостоятельных рецептов. Каждый из них состоит из следующих частей.

Задача — описание типичного сценария разработки, в котором может быть использован JavaScript.

• Решение — решение задачи с примером кода и минимальным описанием.

Обсуждение — подробное обсуждение примера кода и применяемых методик.

Кроме того, в рецепте могут присутствовать разделы «Читайте также» со списком литературы, рекомендованной для дальнейшего чтения, и «Дополнительно» с описанием других методик.

Условные обозначения

В этой книге использованы следующие условные обозначения.

Курсив

Курсивом выделены новые термины.

Рубленый шрифт

Этим шрифтом выделены элементы пользовательского интерфейса, URL, адреса электронной почты и названия клавиш.

Моноширинный шрифт

Любой компьютерный код — команды, массивы, элементы, операторы, опции, переключатели, переменные, атрибуты, ключи, функции, типы, классы, пространства имен, методы, модули, свойства, параметры, значения, объекты, события, обработчики событий, XML- и HTML-теги, макросы, названия и содержимое файлов, результаты работы команд.

Моноширинный жирный шрифт

Команды и другой текст, который должен вводить пользователь.

Этот значок обозначает обычное примечание.

Этот значок обозначает совет или рекомендацию.

Этот значок обозначает предупреждение или предостережение.

Вам также могут пригодиться упоминаемые в книге сайты и веб-страницы — это упростит поиск информации онлайн. Обычно приводится адрес (URL) и название (заглавие или другой подходящий заголовок) этих ресурсов. Некоторые адреса довольно длинные, так что вам, возможно, будет проще найти такие страницы, введя их название в той поисковой системе, которой вы обычно пользуетесь. Названия помогут и в том случае, если страницу не удастся найти по адресу: URL может измениться, но название страницы останется прежним.

Примеры кода

Вспомогательные материалы (примеры кода, упражнения и т.п.) доступны для скачивания по адресу https://github.com/javascripteverywhere/cookbook.

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

Мы рекомендуем, но не требуем добавлять ссылку на первоисточник при цитировании. Под ссылкой на первоисточник мы подразумеваем указание авторов, издательства и ISBN.

За получением разрешения на использование значительных объемов программного кода из книги обращайтесь по адресу permissions@oreilly.com.

Благодарности

Это третье издание книги «JavaScript. Рецепты для разработчиков». Первые два были написаны Шелли Пауэрс. Третье издание написали и обновили Адам Скотт и Мэтью Макдоналд. Адам и Мэтью благодарят своих редакторов Анджелу Руфино и Дженнифер Поллок, которые сопровождали проект на протяжении всего периода его трудного взросления; Сару Вакс, Шайка Нитлинга и Элизабет Робсон, которые сделали множество тонких замечаний и полезных предложений. Адам также благодарен Джону Пакстону за поддержку и общение на ранних стадиях работы над книгой.

Шелли благодарит своих редакторов Симона Сен-Лорана и Брайана Макдоналда, а также доктора Акселя Раушмайера и Семми Пьюруол.

Все вместе мы благодарим производственный персонал O’Reilly за постоянную помощь и поддержку.

От издательства

Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).

Мы будем рады узнать ваше мнение!

На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.

Часть I. Язык JavaScript

Глава 1. Настройка среды разработки

Возможно, вам приходилось слышать, что «разработчика делают инструменты разработки». Это, конечно же, преувеличение, но никто не захочет остаться один на один с кодом JavaScript без любимых инструментов для редактирования, анализа и отладки.

При настройке среды разработки первое, чем вы озаботитесь, — это редактор кода. Даже в самом простом редакторе есть такие базовые вещи, как автодополнение и подсветка синтаксиса — две простые функции, предотвращающие кучу потенциальных ошибок. В современных редакторах кода функций гораздо больше. В частности, это интеграция с системами управления версиями, такими как GitHub, построчная отладка и интеллектуальный рефакторинг. Некоторые из этих функций подключаются к редактору в виде плагинов. Иногда функции запускаются из терминала или являются частью процесса сборки. Но как бы вы ни использовали свой инструментарий, подобрать удачное сочетание инструментов, соответствующее вашему стилю программирования, среде разработки и типам проектов, — обязательная часть общего удовольствия. Это примерно такая же обязательная процедура, как приобретение инструментов для профессионала, занимающегося ремонтом квартир, или инвестиции в правильное кухонное оборудование для амбициозного шеф-повара.

Инструменты не выбирают раз и навсегда. Ваши предпочтения как разработчика могут меняться. По мере профессионального роста, а также при появлении новых полезных инструментов ваш инструментарий будет расширяться. В этой главе описан минимальный комплект, которым необходимо обзавестись любому разработчику JavaScript, прежде чем браться за проект. Однако у вас остается широчайший выбор между различными, но в целом эквивалентными вариантами. И как отмечают многие мудрые люди, о вкусах не спорят!

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

1.1. Выбираем редактор кода

Задача

Использовать для написания кода редактор, который понимает синтаксис JavaScript.

Решение

Если вы спешите, то не ошибетесь, выбрав наш любимый Visual Studio Code, который для краткости часто называют VS Code. Этот бесплатный редактор с открытым кодом существует в версиях для Windows, Macintosh и Linux.

Если у вас есть время на поиски, то можете обратить внимание на несколько других редакторов. Их список, приведенный в табл. 1.1, далеко не полон, но в нем перечислены самые популярные редакторы.

Таблица 1.1. Автономные редакторы кода

Редактор

Поддерживаемые платформы

Открытый код

Стоимость

Примечания

Visual Studio Code (https://code.visualstudio.com)

Windows, Macintosh, Linux

Да

Бесплатно

Отличный редактор для любого языка и наш выбор номер один для разработки на JavaScript

Atom (https://atom.io)

Windows, Macintosh, Linux

Да

Бесплатно

Большинство глав этой книги написаны с использованием Atom с плагинами для поддержки AsciiDoc

WebStorm (https://jetbrains.com/webstorm)

Windows, Macintosh, Linux

Нет

Бесплатно для разработки ПО с открытым кодом и для образовательных целей, иначе примерно 60 долларов в год на пользователя

Более сложная среда — скорее традиционная IDE, чем редактор кода

Sublime Text (https://sublimetext.com)

Windows, Macintosh, Linux

Нет

Однократный платеж 80 долларов на пользователя без контроля за лицензированием или ограничений по времени

Популярный редактор, известный быстрой обработкой больших текстовых файлов

Brackets (http://brackets.io)

Windows, Macintosh

Да

Бесплатно

Спонсируемый Adobe проект, ориентированный на веб-разработку

Какой бы редактор кода вы ни выбрали, для того чтобы начать новый проект, вам потребуется выполнить примерно одни и те же операции. Вначале создайте папку проекта (например, test-site). Затем откройте редактор кода, найдите команду наподобие FileOpen Folder и выберите созданную папку проекта. В большинстве редакторов кода сразу откроется панель с содержимым этой папки, представленным в виде удобного списка или дерева, чтобы можно было быстро переключаться между файлами.

В папке проекта вы также будете размещать используемые пакеты (рецепт 1.7), сохранять файлы конфигурации приложения и правила кодирования (рецепт 1.10). Кроме того, у редактора есть встроенный терминал (см. подраздел «Дополнительно: терминал и оболочка» далее), который всегда запускается из папки текущего проекта.

Обсуждение

Рекомендовать лучший редактор — все равно что выбирать десерт другому человеку. Подходящих вариантов не менее дюжины, и при выборе не последнюю роль играют личные предпочтения. Большинство предложений, перечисленных в табл. 1.1, соответствуют всем основным требованиям.

• Кроссплатформенность — не имеет значения, какую операционную систему вы используете.

• Поддержка плагинов — можно подключить все необходимые функции. Многие инструменты, упоминаемые в книге (такие как форматировщик кода Prettier, описанный в рецепте 1.10), реализованы в виде плагинов, которые подключаются к различным редакторам кода.

• Мультиязычность — это позволит писать код не только на HTML, CSS и JavaScript, но и на других языках программирования.

• Поддержка сообщества — благодаря этому вы можете быть уверены, что выбранный редактор будет еще долго поддерживаться и совершенствоваться.

• Свободное распространение или разумная цена.

VS Code, который мы посчитали наилучшим вариантом, — это редактор кода от Microsoft со встроенной поддержкой JavaScript. Сам редактор тоже написан на JavaScript и размещен на платформе Electron. (Точнее, редактор написан на TypeScript — более строгом варианте JavaScript, который компилируется в JavaScript перед дистрибуцией или выполнением.)

VS Code во многих отношениях является стильным младшим братом массивной IDE Visual Studio, которая также существует в бесплатной редакции Community и тоже позволяет писать код на JavaScript. Но VS Code лучше подходит для тех разработчиков, которые уже не работают со стеком Microsoft.NET. Такого удачного баланса удалось достичь благодаря тому, что изначально VS Code очень прост, но его можно до бесконечности настраивать благодаря библиотеке, насчитывающей сотни разрабатываемых сообществом плагинов (https://oreil.ly/RvMZ9). В обзорах для разработчиков, публикуемых на Stack Overflow, VS Code постоянно упоминается как самый популярный редактор кода для разных языков программирования.

Читайте также

Для того чтобы познакомиться с основными функциями и общей структурой VS Code, советуем посмотреть отличный набор начальных видеоуроков (https://oreil.ly/iiRhA). В этой главе вы научитесь применять сокращенные команды Emmet для VS Code (рецепт 1.5), а также подключать плагины ESLint (рецепт 1.10) и Prettier (рецепт 1.11).

1.2. Использование консоли разработки в браузере

Задача

Иметь возможность просматривать сообщения об ошибках на веб-странице и информацию, которую мы сами выводим в консоль.

Решение

Для этого мы будем использовать консоль разработки в браузере. В табл. 1.2 показано, как открыть инструменты разработки во всех современных браузерах.

Таблица 1.2. Сочетания клавиш, чтобы открыть консоль разработки     1

Браузер

Операционная система

Сочетание клавиш

Chrome

Windows или Linux

F12 или Ctrl+Shift+J

Chrome

Macintosh

Cmd-Option-J

Edge

Windows или Linux

F12 или Ctrl+Shift+J

Firefox

Windows или Linux

F12 или Ctrl+Shift+J

Firefox

Macintosh

Cmd-Shift-J

Safari1

Macintosh

Cmd-Option-C

Opera

Windows

Ctrl+Shift+J

Opera

Macintosh

Cmd-Option-J

Как правило, инструменты разработки представляют собой группу панелей со вкладками и размещаются в правой или нижней части окна браузера. Сообщения, которые выводятся с помощью console.log(), а также сообщения об ошибках появляются на панели Console.

Вот полный код страницы, которая выводит текст в консоль и затем завершается с ошибкой:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="UTF-8" />

        <meta name="viewport" content="width=device-width, initial-scale=1.0" />

        <meta http-equiv="X-UA-Compatible" content="ie=edge" />

        <title>Log and Error Test</title>

    </head>

    <body>

        <h1>Log and Error Test</h1>

<script>

    console.log('This appears in the developer console');

</script>

<script>

    // Этот код вызовет ошибку, сообщение о которой

    // появится в консоли

    const myNumber =

</script>

    </body>

</html>

На рис. 1.1 показано, что появится в консоли разработчика при отображении этой страницы. Первым будет показано выводимое сообщение, а затем — сообщение

Рис. 1.1. Просмотр содержимого консоли разработки в Chrome

об ошибке (SyntaxError с текстом Unexpected end of input). Ошибки выводятся красным цветом, каждое такое сообщение Chrome любезно сопровождает ссылкой, благодаря которой можно быстро перейти к исходному коду и увидеть, что именно стало причиной ошибки. Строки веб-страниц и файлов со сценариями автоматически нумеруются. В данном примере легко отличить код с выводом сообщения (строка 13) от кода, который вызвал ошибку (закрывающий тег </script> в строке 19).

Обсуждение

В книге мы будем постоянно использовать конструкцию console.log() для быстрого вывода тестовых сообщений. Но у объекта console есть и другие методы, которыми можно пользоваться. Самые полезные методы приводятся в табл. 1.3.

Таблица 1.3. Методы объекта console

Метод

Описание

console.warn(object)

Аналог console.log(), но текст выводится на желтом фоне

console.error(object)

Аналог console.log(), но текст выводится на красном фоне. Обычно используется для вывода объектов с сообщениями об ошибках

console.assert(expression, object)

Если значением выражения (expression) является false, то сообщение (message) выводится в консоли с трассировкой стека

console.trace()

Вывод трассировки стека

console.count(label)

Вывод количества вызовов метода с данным именем (label)

console.dir(object)

Вывод всех свойств объекта в виде разворачивающегося древовидного списка

console.group()

Создает новую группу с заданным именем. Все последующие сообщения в консоли выводятся под этим заголовком и с отступом, так что кажутся логически связанными частями одного раздела. Чтобы закрыть группу, используется метод console.groupEnd()

console.time(label)

Запускает таймер с заданным названием (label)

console.timeEnd(label)

Останавливает таймер с заданным названием (label) и выводит истекшее время

В консолях современных браузеров часто используется отложенное вычисление объектов и массивов. Такая ситуация может возникать, если вывести объект с помощью console.log(), изменить его, а потом вывести этот объект еще раз. Если делать это в коде сценария на веб-странице, то зачастую можно обнаружить, что console.log() выводит один и тот же уже измененный объект, несмотря на то что первый вызов произошел до того, как объект был изменен!

Чтобы избежать этой причуды браузера, нужно перед выводом явно преобразовать объект в строку. Этот трюк сработает, поскольку консоль не выполняет отложенных вычислений для строк. Так делать не всегда удобно (например, это не поможет, если нужно вывести массив, в состав которого входят объекты), но в большинстве случаев это решает проблему.

Разумеется, консоль — это лишь одна из панелей (или вкладок) раздела с инструментами разработки. Осмотревшись, вы обнаружите еще несколько полезных функций, расположенных на других панелях. Их точное расположение и названия зависят от браузера. Далее перечислены некоторые из основных таких функций для Chrome.

Elements. На этой панели можно увидеть разметку HTML для тех или иных частей страницы и проверить, какие стили CSS применяются к отдельным элементам. Можно даже изменить эту разметку и стили (временно), чтобы быстро увидеть результат изменений, которые вы намерены внести.

• Sources. На данной панели можно просмотреть содержимое всех файлов, которые используются для данной страницы, включая библиотеки JavaScript, изображения и таблицы стилей.

• Network. На этой панели можно увидеть размер и время загрузки страницы и ее ресурсов, а также прочитать асинхронные сообщения, передаваемые по сети (например, при запросе fetch).

• Performance. Эту панель используют, чтобы отслеживать время выполнения кода (см. рецепт 11.2).

Application. Здесь можно увидеть все данные, которые этот сайт хранит в cookie — как в локальном хранилище, так и с помощью API IndexedDB.

Советуем поэкспериментировать с этими панелями, чтобы получить представление о том, как они работают, или ознакомиться с документацией, предоставляемой Google (https://oreil.ly/cZ6AP).

Читайте также

В рецепте 1.3 показано, как быстро выполнить фрагмент кода в консоли разработчика.

1.3. Выполнение фрагментов кода в консоли разработчика

Задача

Иметь возможность выполнить фрагмент кода, не открывая его в редакторе и не создавая файлы для HTML и JavaScript.

Решение

Воспользуемся консолью разработки в браузере. Откройте средства разработки (как описано в рецепте 1.2). Выберите панель Console. Вставьте или введите в ней код JavaScript.

Чтобы сразу выполнить код, нажмите клавишу Enter. Если хотите выполнить несколько строк кода, то нажимайте в конце каждой строки Shift+Enter, чтобы вставить мягкий перевод строки. Нажимайте Enter только после того, как закончите ввод кода и захотите выполнить весь код.

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

На рис. 1.2 показан пример, где фрагмент кода в первый раз не выполнился из-за синтаксической ошибки. Затем этот код был извлечен из истории, изменен и снова выполнен. Результат выполнения (число 15) появился в консоли под кодом.

Функция истории работает только до тех пор, пока вы не начнете вводить новый код. Если командная строка консоли не пустая, то при нажатии клавиши со стрелкой вверх вы не вернете предыдущий фрагмент, а будете перемещаться по текущему блоку кода.

Обсуждение

В консоли разработчика можно вводить код JavaScript точно в том же виде, что и в блоке сценария. Другими словами, вводить функции и вызывать их или определить класс и создать его экземпляр. Можно также обращаться к объекту document, взаимодействовать с элементами HTML, размещенными на текущей странице, выводить предупреждения и текст в консоль. (Сообщения будут появляться сразу под кодом.)

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

const testValue = 40+12;

console.log(testValue);

Рис. 1.2. Выполнение кода в консоли

Если выполнить его один раз, все сработает хорошо. Но если вызвать его из истории (нажав клавишу со стрелкой вверх), отредактировать и попробовать запустить снова, то получим ошибку с сообщением о том, что переменная testValue уже объявлена. Конечно, эту переменную можно переименовать, но если вы пытаетесь усовершенствовать фрагмент кода с несколькими переменными и функциями, то такое переименование быстро станет неудобным. Вместо этого можно выполнить команду location.reload(), чтобы обновить страницу, но обновление сложных страниц может выполняться медленно. Кроме того, при обновлении можно потерять какое-то состояние страницы, которое вы хотели бы сохранить.

К счастью, у этой проблемы есть более простое решение. Заключите весь блок в пару скобок, чтобы получилась новая область видимости имен. Теперь можно спокойно выполнять этот код сколько угодно раз, поскольку каждый раз будет создаваться новый контекст (и удаляться по окончании выполнения):

{

    const testValue = 40+12;

    console.log(testValue);

}

Читайте также

В рецепте 11.1 продемонстрировано искусство отладки в консоли разработки. В рецепте 11.2 показано, как можно применять консоль разработки для анализа производительности.

1.4. Использование строгого режима для выявления типичных ошибок

Задача

Запретить использование потенциально опасных операций, таких как автоматическое создание переменных или операторы, которые могут не выполняться и никак не сообщать об этом.

Решение

Поставьте в начале файла с кодом JavaScript директиву strict:

'use strict';

Или можно оформить код JavaScript в виде модуля, который всегда запускается в строгом режиме (рецепт 8.9).

Обсуждение

JavaScript пользуется в некоторой степени заслуженной репутацией языка, терпимого к небрежно написанному коду. Проблема в том, что языки, игнорирующие мелкие нарушения правил, ставят разработчиков в невыгодное положение. В конце концов, вы не сможете исправить ошибку, если не узнаете о ней.

Далее показан пример плохого кода на JavaScript. Сможете ли вы найти в нем ошибку?

// Эта функция суммирует последовательные числа

function addRange(start, end) {

    let sum = 0;

    for (let i = start; i < end+1; i++) {

        sum += i;

    }

    return sum;

}

// Суммируем числа от 10 до 15

let startNumber = 10;

let endNumber = 15;

console.log(addRange(startNumber,endNumber)); // Выведет 75

// Теперь суммируем числа от 1 до 5

startnumber = 1;

endNumber = 5;

console.log(addRange(startNumber,endNumber)); // Выведет 0, а не 15,

                                              // как ожидалось

Код выполнится без ошибок, но результат будет не тот, которого мы ожидали. Проблема кроется в этой строке:

startnumber = 1;

Дело в том, что если вы пытаетесь присвоить значение переменной, которую не объявили явно, то JavaScript создает эту переменную. Поэтому, если присвоить значение переменной startnumber, в то время как имелась в виду startNumber, JavaScript тихо создаст переменную startnumber. В результате значение, которое мы хотели присвоить startNumber, попадет в другую переменную, и мы его больше никогда не увидим и не сможем использовать.

Чтобы устранить эту проблему, нужно поставить в начале файла, перед кодом функции, директиву строгого режима:

'use strict';

Теперь, когда JavaScript дойдет до присвоения значения переменной startnumber, появится сообщение об ошибке ReferenceError. Выполнение кода будет прервано, работа сценария завершится. При этом в консоли появится набранное красными буквами сообщение об ошибке. В нем будет описана проблема и указан номер строки, в которой произошла ошибка. Теперь исправить ошибку очень просто.

Строгий режим позволяет отловить множество мелких, но зловредных ошибок. Вот лишь некоторые из них.

• Присвоение значений необъявленным переменным.

• Дублирование имен параметров (например, function(a, b, a)) или имен свойств объектных литералов (например, {a: 5, a: 0}).

• Попытки присвоить значения зарезервированным ключевым словам, таким как Infinity или undefined.

• Попытки изменить неизменяемые свойства (рецепт 7.7) или заблокированные объекты (рецепт 7.8).

Многие из таких действий не удалось бы выполнить и без использования строгого режима. Но это произошло бы тихо и, возможно, привело бы к печальной ситуации, когда код работает не так, как нужно, а вы понятия не имеете, почему это происходит.

Скорее всего, ваш редактор кода можно настроить так, чтобы директива use strict по умолчанию вставлялась во все создаваемые файлы. Например, у Visual Studio Code есть как минимум три небольших расширения (https://oreil.ly/ye0o7), которые это делают.

Строгий режим позволяет отловить не так уж много ошибок. Большинство разработчиков используют также инструмент статического анализа кода (рецепт 1.10), способный обнаруживать гораздо более широкий спектр ошибок и потенциально рискованных операций. Собственно говоря, разработчики так сильно полагаются на анализаторы кода, что иногда не утруждают себя включением строгого режима. Однако его рекомендуется применять всегда как простейшее средство гарантировать, что вы не выстрелите сами себе в ногу.

Читайте также

Подробнее о том, что невозможно сделать при активированном строгом режиме, читайте в документации строгого режима (https://oreil.ly/Z7QhF). Использование модулей, которые всегда выполняются в строгом режиме, описано в рецепте 8.9.

1.5. Вставка блоков HTML с помощью сокращенных команд Emmet

Задача

Иметь возможность вставить в файл большой кусок стандартного HTML, не вбивая руками каждый открывающий и закрывающий тег.

Решение

Emmet — это функция редактора, которая автоматически заменяет предопределенные текстовые сокращения на стандартные блоки HTML. В некоторых редакторах кода, таких как Visual Studio и WebStorm, Emmet поддерживается изначально. В других редакторах, таких как Atom и Sublime Text, для этого нужно подключать плагины. Чтобы найти нужный плагин, обычно достаточно открыть библиотеку плагинов и ввести Emmet в строке поиска. В случае сомнений загляните в список плагинов для поддержки Emmet (https://emmet.io/download).

Для того чтобы использовать Emmet, создайте пустой файл и сохраните его с расширением .html или .htm, чтобы редактор кода распознал его как документ HTML. Затем введите одно из сокращений Emmet и нажмите клавишу табуляции. (В некоторых редакторах нужна другая клавиша или комбинация клавиш — это может быть Enter или Ctrl+E, но обычно применяется табуляция.) Введенный текст будет автоматически преобразован в соответствующий блок или элемент разметки.

Например, сокращение Emmet input:time преобразуется в следующий элемент:

<input type="time" name="" id="" />

На рис. 1.3 показано, как VS Code распознает сокращение Emmet по мере ввода. В VS Code поддерживается автодополнение сокращенных команд Emmet, так что вы увидите возможные варианты. В меню автодополнения выводится примечание Emmet Abbreviation, которое показывает, что сейчас вы набираете не HTML-код, а сокращенную команду Emmet, которая будет преобразована в HTML.

Рис. 1.3. Использование Emmet в VS Code

Обсуждение

Несмотря на простой синтаксис, Emmet удивительно гибок. Более сложные выражения позволяют создавать вложенные сочетания элементов, назначать атрибуты и вставлять в имена элементов последовательную нумерацию. Например, для того чтобы создать маркированный список из пяти элементов, используется сокращение ul>li*5, в результате чего в разметку HTML будет вставлен следующий блок:

<ul>

    <li></li>

    <li></li>

    <li></li>

    <li></li>

    <li></li>

</ul>

А с помощью сокращенной команды html:5 можно создать стандартный скелет веб-страницы, отвечающий современному стандарту HTML5:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

</body>

</html>

Все эти функции описаны в документации Emmet (https://docs.emmet.io). Если у вас мало времени, начните с шаблонов, представленных в виде удобной шпаргалки.

1.6. Установка менеджера пакетов npm (с Node.js)

Задача

Установить npm, чтобы быстро загружать библиотеки JavaScript из реестра npm и подключать их к веб-проектам.

Решение

В Node Package Manager (npm) хранится самый большой в мире и самый популярный на сегодняшний день реестр программного обеспечения. Самый простой способ получить программу из npm-реестра — использовать утилиту npm, которая входит в комплект Node.js. Чтобы установить Node, загрузите с сайта Node (https://nodejs.org) установочный пакет для своей операционной системы (Windows, MacOS или Linux).

Закончив установку Node, можете проверить, доступен ли он из командной строки. Для этого откройте окно терминала и введите команду node -v. Чтобы убедиться, что утилита npm тоже установилась, введите npm -v. В обоих случаях вы увидите версии этих пакетов:

$ node -v

v14.15.4

$ npm -v

6.14.10

Обсуждение

Утилита npm входит в состав Node.js — операционной среды JavaScript и веб-сервера. Node можно использовать для выполнения серверных фреймворков JavaScript, таких как Express, или для сборки автономных приложений на JavaScript с помощью Electron. Но даже если вы не собираетесь работать с Node, вам почти наверняка придется его установить хотя бы для того, чтобы получить доступ к менеджеру пакетов npm.

Node Package Manager — это инструмент, позволяющий загружать пакеты из реестра npm: бесплатного каталога, который отслеживает десятки тысяч библиотек JavaScript. Собственно, сегодня едва ли найдется компьютер, который используется для разработки на JavaScript и на котором при этом не установлены Node и npm.

Возможности менеджера пакетов далеко не ограничиваются простой загрузкой полезных библиотек. Менеджер пакетов также отслеживает, какие библиотеки использует проект (они называются зависимостями), загружает пакеты, от которых в свою очередь зависят эти библиотеки (эти пакеты иногда называют подзависимостями), сохраняет информацию о версиях, различает тестовые и эксплуатационные сборки. Благодаря npm можно полностью перенести приложение с одного компьютера и на другой и установить все необходимые зависимости одной командой, как описано в рецепте 1.7.

В настоящее время npm — самый популярный, но далеко не единственный менеджер пакетов для JavaScript. Некоторые разработчики предпочитают Yarn (https://yarnpkg.com), так как считают, что он быстрее устанавливает пакеты. Еще один вариант — Pnpm (https://pnpm.io). Он почти полностью совместим с командной строкой npm, но занимает гораздо меньше места и быстрее устанавливается.

Читайте также

О том, как установить пакет из npm, читайте в рецепте 1.7.

Если вы используете Node (а не только npm) для разработки, то, возможно, стоит установить его с nvm — менеджером версий Node. Тогда вы сможете легко переходить с одной версии Node на другую и быстро обновлять установленный Node по мере появления новых релизов, что происходит довольно часто. По­дробнее об этом читайте в рецепте 17.1. Если же вы не знаете, как запустить на выполнение код в среде Node, то загляните в главу 17, где найдете множество примеров.

Дополнительно: терминал и оболочка

Node и npm запускаются из терминала. Технически терминал — это текстовый интерфейс, который взаимодействует с оболочкой, чтобы выполнять команды. Существует множество программ, реализующих функцию терминала, а также множество оболочек. Выбор терминала и оболочки зависит от используемой операционной системы (и ваших личных предпочтений, поскольку есть множество сторонних альтернатив).

Вот некоторые из наиболее популярных сочетаний терминалов и оболочек, которые могут вам встретиться.

• На компьютере Macintosh перейдите в Applications, откройте папку Utilities и выберите Terminal. Запустится стандартная программа терминала, оболочкой которой служит bash.

• Какая программа терминала будет установлена на компьютере с Linux, зависит от дистрибутива. Обычно она называется Terminal, а в качестве оболочки почти всегда используется bash.

• На компьютере с Windows можно запустить PowerShell из меню Start. Технически PowerShell — это оболочка, заключенная в процесс терминала, который называется conhost. В настоящее время Microsoft разрабатывает современную замену conhost под названием Windows Terminal, которую первые пользователи уже могут установить с Windows Store или загрузить с GitHub (https://github.com/microsoft/terminal). Microsoft также включила оболочку bash в состав Windows Subsystem for Linux (https://oreil.ly/N7EWS), хотя это относительно недавнее дополнение к операционной системе.

• В некоторых редакторах кода есть свои встроенные терминалы. Например, если открыть окно терминала в VS Code, нажав комбинацию клавиш Ctrl+` (это не одиночная кавычка, а обратный апостроф) или выбрав из меню ­команду ViewTerminal, то откроется встроенный терминал VS Code. По умолчанию он взаимодействует с PowerShell в Windows и с bash в остальных операционных системах, но это можно изменить.

Когда мы будем предлагать вам ввести команду терминала, можете использовать окно терминала в редакторе кода, программу терминала, установленную на вашем компьютере, или же любое из многочисленных сторонних приложений терминала и оболочки. Все они принимают одни и те же переменные окружения (то есть имеют доступ к установленным на компьютере Node и npm) и позволяют запускать программы из текущей папки. Вы также можете с помощью терминала решать обычные задачи управления файловой системой, такие как создание папок и файлов.

В книге перед командами, которые нужно вводить в терминале (как в рецепте 1.6), ставится знак $. Это традиционное приглашение ввода для bash. Но в других оболочках могут быть другие соглашения. Так, в PowerShell вместо знака $ вы увидите имя папки, после которого стоит знак > (например, C:\Projects\Sites\WebTest>). Как бы то ни было, команды для запуска утилит, таких как npm, от этого не изменятся.

1.7. Загрузка пакета с помощью npm

Задача

Установить определенный программный пакет из реестра npm.

Решение

Прежде всего необходимо установить на компьютере утилиту npm (о том, как это сделать, см. рецепт 1.6). Если вы это сделали, откройте окно терминала (см. подраздел «Дополнительно: терминал и оболочка» ранее) и перейдите в папку проекта вашего сайта.

Затем создайте файл package.json, если у вашего приложения его еще нет. На самом деле этот файл не является необходимым для установки пакетов, но он вам понадобится для некоторых других задач, таких как восстановление пакетов при переносе разрабатываемого приложения на другой компьютер. Самый простой способ создать файл package.json — воспользоваться командой npm init:

$ npm init -y

Параметр -y (сокращенное от yes) означает, что npm не будет предлагать вам ввести различную информацию о приложении, а просто выберет стандартные значения. Утилита, запущенная без параметра -y, задаст множество вопросов о приложении: имя пакета, описание, версия, лицензия и т.п. Но вам поначалу не нужно указывать все эти подробности (и не факт, что когда-либо понадобится), так что можно спокойно нажимать Enter, чтобы оставить все эти поля пустыми и создать простейший шаблонный файл package.json. Подробнее об описаниях, которые вносятся в файл package.json, читайте в подразделе «Дополнительно: основные сведения о package.json» далее.

После инициализации приложения все готово к установке пакета. Нужно знать точное имя пакета, который вы хотите установить. В соответствии с соглашением имена пакетов npm состоят из слов, набранных строчными буквами и разделенных дефисами, например fs-extra или react-dom. Для того чтобы установить выбранный пакет, нужно выполнить команду npm, указав его имя. Например, для установки популярной библиотеки Lodash требуется выполнить следующую команду:

$ npm install Lodash

Утилита npm заносит имена установленных пакетов в файл package.json, а также записывает подробную информацию о версиях каждого пакета в файл package-lock.json.

При установке пакета npm загружает его файлы в папку node_modules. Например, при установке пакета Lodash в папку проекта test-site файлы сценариев будут размещены в папке test-site/node_modules/Lodash.

Для того чтобы удалить пакет, используется команда npm uninstall:

$ npm uninstall Lodash

Обсуждение

Вся гениальность npm и других менеджеров пакетов станет очевидной, когда вы начнете работать с типичными веб-проектами, насчитывающими полдесятка или более пакетов, каждый из которых зависит от других пакетов. Благодаря тому что все эти зависимости отслеживаются в файле package-lock.json, можно легко понять, что именно нужно данному веб-приложению. Для того чтобы получить полный отчет, требуется перейти в папку проекта и выполнить следующую команду:

$ npm list

Эти пакеты так же легко заново скачиваются при переносе проекта на новый компьютер. Например, если скопировать на другой компьютер веб-сайт с файлами package.json и package-lock.json, но без папки node_modules, то для установки всех зависимых пакетов нужно выполнить следующую команду:

$ npm install

До сих пор мы рассматривали локальную установку пакетов (в составе данного веб-приложения). Но npm также позволяет устанавливать пакеты глобально (в соответствующей системной папке, чтобы все приложения, установленные на компьютере, использовали одни и те же версии пакетов). Большинство программных пакетов предпочтительнее устанавливать локально. Это позволяет гибко выбирать версию пакета: можно задействовать разные версии одного и того же пакета для разных приложений, что гарантирует совместимость. (Эта потенциальная проблема становится еще серьезней, если один пакет зависит от определенной версии другого пакета.) Однако глобальная установка бывает полезной для определенных типов пакетов, в особенности для средств разработки, имеющих утилиты командной строки. В число пакетов, которые иногда устанавливаются глобально, входят create-react-app (используемый для создания проектов React), http-server (для запуска тестового веб-сервера), typescript (для компиляции кода TypeScript в JavaScript) и jest (для автоматического тестирования кода).

Для того чтобы увидеть список всех глобальных пакетов npm, установленных на компьютере, выполните следующую команду:

`npm list -g --depth 0`

Использование параметра --depth гарантирует, что мы увидим только глобальные пакеты верхнего уровня, а не все остальные применяемые ими пакеты. У npm есть еще несколько функций, которые мы не будем здесь рассматривать, в том числе следующие.

• Назначение определенных зависимостей зависимостями разработки — они используются при разработке, но не при развертывании продукта (например, инструмент модульного тестирования). Мы применим эту методику в рецептах 1.9 и 1.10.

• Ревизия используемых зависимостей путем поиска в реестре npm отчета об обнаруженных уязвимостях — чтобы устранить эти зависимости, нужно установить новые версии пакетов (https://oreil.ly/XjkEM).

• Выполнение операций, обычно запускаемых из командной строки, с помощью утилиты npx, которая поставляется в комплекте с npm. Эти операции даже можно выполнять автоматически, внеся их в файл package.json. В число таких операций входит, в частности, подготовка веб-сайта к развертыванию в среде эксплуатации или запуск веб-сервера для тестирования в процессе разработки. Методику использования тестового сервера рассмотрим в рецепте 1.9.

Утилита npm — не единственный менеджер пакетов, применяемый разработчиками JavaScript. Есть еще аналогичный менеджер пакетов Yarn, первоначально разработанный компанией Facebook. В некоторых случаях он обеспечивает лучшую производительность, так как загружает пакеты параллельно и использует кэширование. Исторически сложилось так, что в нем применяются более строгие методы проверки безопасности. Нет никаких причин отказываться от Yarn, но в сообществе разработчиков JavaScript npm по-прежнему остается значительно более популярной утилитой.

Если захотите изучить все, что стоит знать об npm, потратьте некоторое время на чтение документации по ней для разработчиков (https://docs.npmjs.com). Можете также взглянуть на Yarn (https://yarnpkg.com).

Дополнительно: основные сведения о package.json

Файл package.json — это файл конфигурации приложения, который изначально создавался Node, но сейчас используется для достижения множества других целей. В нем хранятся описание проекта, имя автора, лицензия — все это станет важно, когда вы захотите опубликовать свой проект в виде пакета в реестре npm (о том, как это сделать, читайте в рецепте 18.2). Файл package.json позволяет также отслеживать зависимости (пакеты, применяемые приложением): в нем можно хранить дополнительные команды конфигурации, выполняемые при отладке и развертывании приложения.

Файл package.json рекомендуется создать сразу, в самом начале работы над проектом. Это можно сделать вручную или с помощью команды npm init -y, которую мы использовали в примерах этой главы. Сгенерированный файл package.json выглядит так (если папка проекта называется test_site):

{

    "name": "test_site",

    "version": "1.0.0",

    "description": "",

    "main": "index.js",

    "scripts": {

        "test": "echo \"Error: no test specified\" && exit 1"

    },

    "keywords": [],

    "author": "",

    "license": "ISC"

}

Легко заметить, что в package.json используется формат JSON (JavaScript Object Notation). Этот файл состоит из заключенного в фигурные скобки списка параметров, разделенных запятыми. Файл package.json всегда можно изменить с помощью редактора кода.

При установке пакета с помощью npm эта зависимость заносится в файл package.json как значение свойства dependencies. Например, после установки пакета Lodash package.json будет выглядеть так:

{

    "name": "test_site",

    "version": "1.0.0",

    "description": "",

    "main": "index.js",

    "scripts": {

        "test": "echo \"Error: no test specified\" && exit 1"

    },

    "keywords": [],

    "author": "",

    "license": "ISC",

    "dependencies": {

        "lodash": "^4.17.20"

    }

}

Не следует путать файлы package.json и package-lock.json. В package.json хранятся основные параметры проекта и список применяемых пакетов. В package-lock.json указываются версии и контрольные суммы для всех подключенных вами пакетов, а также версии и контрольные суммы всех используемых ими пакетов. Например, автоматически сгенерированный файл package-lock.json после установки пакета Lodash выглядит так:

{

    "name": "test-site",

    "version": "1.0.0",

    "lockfileVersion": 1,

    "requires": true,

    "dependencies": {

        "lodash": {

            "version": "4.17.20",

            "resolved": "https://registry.npmjs.org/Lodash/-/Lodash-4.17.20.tgz",

            "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlr

             qzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="

        }

    }

}

Другими словами, файл package-lock.json привязывает пакеты к определенной версии. Это пригодится при развертывании проекта на другом компьютере, если вы захотите установить там те же самые версии всех пакетов, ранее использованных при разработке.

Есть две причины, по которым чаще всего приходится изменять файл package.json. Во-первых, чтобы внести туда дополнительные описания, обес­печивающие полноту проекта, прежде чем передавать его кому-то другому. Если вы пожелаете распространять пакет через реестр npm (см. рецепт 18.2), то наверняка захотите гарантировать правильность этой информации. Во-вторых, чтобы внести в файл package.json операции командной строки, выполняемые при отладке приложения, такие как запуск тестового сервера (рецепт 1.9). Полное описание всех свойств, которые могут использоваться в файле package.json, вы найдете в документации по npm (https://oreil.ly/n9PkO).

1.8. Обновление пакета с помощью npm

Задача

Установить свежую версию npm-пакета.

Решение

Для незначительных обновлений можно взять команду npm update. В ней нужно указать имя пакета, который требуется обновить. Или же с помощью утилиты npm можно проверить наличие новых версий для всех пакетов, используемых сайтом, и обновить их все одним махом:

$ npm update

Утилита npm прочитает файл package.json, обновит все зависимости и подзависимости указанных в нем пакетов, загрузит все недостающие пакеты и внесет новые версии в файл package-lock.json.

Обсуждение

Рекомендуется регулярно обновлять используемые пакеты. Однако не все обновления выполняются автоматически. Утилита npm выполняет обновления по правилам семантической верификации (semantic versioning, semver). Она устанавливает обновления, которые имеют больший номер патча (например, 2.1.3 вместо 2.1.2) или дополнительный номер версии (2.2.0 вместо 2.1.2), но не обновляет зависимость в том случае, если у нового релиза изменился основной номер версии (3.0.0 вместо 2.1.2). Благодаря такому поведению работа приложения не нарушится при обновлении или развертывании.

Чтобы просмотреть доступные обновления для всех применяемых зависимостей, можно воспользоваться командой npm outdated:

$ npm outdated

Результат будет выглядеть примерно так:

Package                Current     Wanted     Latest    Location

-------                -------     ------     ------    --------

eslint                  7.18.0     7.25.0     7.25.0    my-site

eslint-plugin-promise    4.2.1      4.3.1      5.1.0    my-site

Lodash                 4.17.20    4.17.21    4.17.21    npm-test

В столбце Wanted показаны доступные обновления, которые будут установлены при следующем выполнении команды npm update. В столбце Latest представлены последние версии пакетов. В данном примере пакеты Lodash и eslint могут быть обновлены до последних версий, а пакет eslint-plugin-promise — только до версии 4.3.1. Последняя версия этого пакета — 5.1.0, то есть изменился главный номер версии, поэтому в соответствии с правилами семантической верификации он не может быть обновлен автоматически.

Это немного упрощенное представление. Утилита npm позволяет настраивать политику управления версиями с помощью файла package.json. Но на практике режим обновлений, предлагаемый в npm по умолчанию, почти всегда работает хорошо. Подробнее об управлении версиями в npm читайте в документации по npm (https://oreil.ly/NX8js).

Обновлять зависимости до новой главной версии необходимо специально. Для этого нужно либо вручную внести изменения в файл package.json (что несколько хлопотно), либо воспользоваться инструментом, который сделает это за вас, таким как npm-check-updates (https://oreil.ly/0JcMt). Утилита npm-check-updates позволяет просмотреть список зависимостей, найти те, для которых есть обновления, и внести изменения в файл package.json, чтобы разрешить установку новых главных версий для этих пакетов. Затем, чтобы установить новые версии, нужно вызвать команду npm update.

1.9. Настройка локального тестового сервера

Задача

Иметь возможность тестировать веб-страницы в процессе разработки без локальных ограничений в сфере безопасности и без развертывания на рабочем веб-сервере.

Решение

Установите на компьютере локальный тестовый сервер. Он будет обрабатывать запросы и передавать веб-страницы в браузер так же, как это сделал бы обычный веб-сервер. Единственное отличие состоит в том, что тестовый сервер не будет устанавливать удаленные соединения с другими компьютерами.

Есть множество вариантов тестовых серверов (см. раздел «Обсуждение»). Из них два самых простых и надежных — это пакеты http-server и lite-server, которые устанавливаются посредством npm. В этой книге мы будем использовать пакет lite-server, поскольку у него есть функция автоматического обновления, которая обновляет страницы в браузере сразу после сохранения измененного в редакторе кода.

Прежде чем устанавливать пакет lite-server, стоит создать простую веб-страницу, чтобы было на чем проверить его работу. Если у вас еще нет такой страницы, создайте папку проекта и настройте его конфигурацию с помощью команды npm init -y (см. рецепт 1.7). Затем создайте файл index.html с простейшим содержимым. Если вы торопитесь, то вот минимальный корректный HTML-документ, с помощью которого можно проверить, работает ли ваш код:

<!DOCTYPE html>

<html lang="en">

    <head>

        <meta charset="utf-8">

        <title>Test Page</title>

    </head>

    <body>

        <p>This is the index page</p>

        <script>

if (window.location.protocol === 'file:') {

    console.log('Running as local file!');

}

else if (window.location.host.startsWith('localhost')) {

    console.log('Running on a local server');

}

else {

    console.log('Running on a remote web server');

}

        </script>

    </body>

</html>

Теперь можно сделать так, чтобы этот документ открывался в браузере с помощью тестового сервера.

Для установки lite-server нужно вызвать команду npm с параметром --save-dev. Таким образом мы указываем, что данная зависимость является зависимостью разработки и не должна развертываться при сборке готового продукта:

npm install lite-server --save-dev

Теперь запустим lite-server непосредственно из окна терминала с помощью утилиты запуска пакетов npx:

npx lite-server

Эта утилита запустит lite-server, откроет новую вкладку в браузере и выполнит запрос http://localhost:3000, где 3000 — порт, который динамически назначается lite-server. Далее lite-server попытается вернуть index.html либо, если не найдет файл с таким именем, выведет сообщение Cannot GET /. Если вы использовали образец страницы, представленный в этом разделе, то на ней появится текст This is the index page, а в консоли разработки — сообщение Running on a local server. Если на вашем тестовом сайте нет страницы index.html, можете загрузить другую страницу, изменив URL в строке адреса (например, http://localhost:3000/someOtherPage.html).

Теперь давайте что-нибудь изменим. Экземпляр lite-server отслеживает папку проекта. Когда вы вносите изменения в файл, сервер автоматически обновляет соответствующую страницу в браузере. В терминале при этом каждый раз выводится сообщение Reloading Browsers.

Чтобы остановить сервер, перейдите в терминал, нажмите Ctrl+C (на Macintosh — Command-C) и введите Y в ответ на последующий вопрос. Или же закройте окно терминала (в VS Code можно воспользоваться значком Kill Terminal с изображением корзины для мусора).

Внутри lite-server применяется популярный инструмент автоматизации браузера BrowserSync (https://oreil.ly/tAwyk) — именно он обеспечивает автоматическую перезагрузку страниц. Для этого на веб-странице обязательно должен быть раздел <body> (Создайте простейшую тестовую страницу без этого элемента — и увидите, что автоматического обновления не происходит.)

Обсуждение

Мы и без тестового сервера можем сохранить веб-страницу на локальном компьютере, открыть ее в веб-браузере и выполнить размещенный на ней код. Но веб-браузеры сильно ограничивают возможности страниц, открываемых из локальной файловой системы. Целые функции, такие как веб-процессы, ES-модули и некоторые операции с Canvas, окажутся недоступными и не будут работать, никак об этом не сообщая. Чтобы не натыкаться на эти барьеры системы безопасности или, что еще хуже, не понимать, почему приложение не работает так, как нужно, стоит всегда открывать веб-страницы с тестового веб-сервера.

При тестировании обычно используется сервер разработки. Таких серверов много, и ваш выбор до определенной степени будет зависеть от серверных технологий, которые вы планируете задействовать. Например, если на страницах будет выполняться код PHP, то вам понадобится сервер, поддерживающий этот язык. Если планируете собрать серверную часть своего приложения с помощью JavaScript или серверных фреймворков на базе JavaScript, таких как Express, то нужен Node.js. Но для обычных веб-страниц с клиентским JavaScript подойдет простой сервер, способный передавать статические файлы, например http-server или lite-server. Таких серверов очень много, и у многих редакторов кода есть собственные плагины тестовых серверов. Например, в библиотеке расширений для Visual Studio Code вы найдете популярный плагин Live Server (https://oreil.ly/NIrRK).

В разделе «Решение» было показано, как запустить lite-server с помощью команды npx. Но удобнее создать задачу разработки, которая будет запускать сервер автоматически. Для этого нужно открыть файл package.json и добавить в раздел scripts следующее:

{

...

    "scripts": {

        "dev": "lite-server"

    }

}

В разделе scripts содержатся задачи, которые должны выполняться регулярно. Это может быть проверка кода синтаксическим анализатором и системой управления версиями, упаковка файлов для развертывания или выполнение модульного тестирования. Этих задач может быть сколько угодно. Например, типичный набор — одна задача для запуска приложения, еще одна — для автоматизированного тестирования с помощью соответствующего инструмента (см. рецепт 10.7), еще одна — для подготовки к развертыванию и т.д. В нашем примере сценарий называется dev, что в соответствии с соглашением означает задачу, которая выполняется при разработке приложения.

После того как сценарий занесен в файл package.json, его можно выполнить в терминале с помощью команды npm run:

npm run dev

В результате будет вызвана утилита npx, с помощью которой будет запущен lite-server.

Некоторые редакторы кода поддерживают такую возможность дополнительной настройки. Например, если открыть файл package.json в VS Code, то непосредственно над параметром dev появится ссылка Debug. Если щелкнуть на ней, то в VS Code откроется новое окно терминала, в котором автоматически запустится lite-server.

Читайте также

Для получения более подробной информации об использовании Node в качестве тестового сервера читайте рецепты из главы 17. Подробнее о выполнении задач с помощью npm можно узнать из обзора, размещенного по адресу https://oreil.ly/nq31H.

1.10. Соблюдение стандартов кодирования с помощью статического анализатора

Задача

Стандартизировать код JavaScript, обеспечить соблюдение рекомендаций и избегать типичных подводных камней, которые приводят к появлению ошибок.

Решение

Проверьте код с помощью статического анализатора (linter). Он предупредит вас, если вы отступите от правил, которым решили следовать. Самым популярным статическим анализатором JavaScript является ESLint.

Для того чтобы использовать ESLint, его вначале нужно установить с помощью npm (см. рецепт 1.6). Перейдите в папку проекта и откройте окно терминала. Если вы еще не создали файл package.json, то сделайте это с помощью следующей команды npm:

$ npm init -y

Затем установите пакет eslint с параметром --save-dev — нам нужно, чтобы ESLint был зависимостью разработчика и устанавливался только на компьютер, на котором разрабатывается проект, но не на рабочий сервер:

$ npm install eslint --save-dev

Если у вас еще нет конфигурационного файла ESLint, то нужно его создать. Для настройки ESLint используется следующая команда npx:

$ npx eslint --init

ESLint задаст несколько вопросов, чтобы определить тип правил, за соблюдением которых нужно следить. Часто предлагается меню с вариантами выбора, между которыми можно переключаться при помощи клавиш со стрелками.

Первый вопрос: How would you like to use ESLint? (Как вы хотите использовать ESLint?). На него есть три варианта ответа, от менее жесткого до самого жесткого.

Только проверка синтаксиса. В режиме Check syntax only ESLint просто находит ошибки и не делает ничего более серьезного, чем обычная функция проверки ошибок, которая есть в большинстве редакторов кода.

• Проверка синтаксиса и поиск проблем. В режиме Check syntax and find problems активируются рекомендованные правила ESLint (https://eslint.org/docs/rules) — те, что отмечены флажками. Этот режим — отличная начальная точка, впоследствии при желании вы сможете переопределить некоторые из этих правил.

Проверка синтаксиса, поиск проблем, проверка стиля программирования. Режим Check syntax, find problems, and enforce code style хорошо подходит для тех случаев, когда нужно использовать определенный стиль программирования на JavaScript, например стандарт Airbnb (https://github.com/airbnb/javascript), чтобы обеспечить соблюдение дополнительных соглашений по стилю программирования. Если выбрать этот вариант, то вам будет предложено указать соответствующее руководство по оформлению кода.

За этим последует ряд технических вопросов: используете ли вы модули, фреймворк React или Vue либо язык TypeScript? Если нужна поддержка стандартов модулей ES6 (они описываются в рецепте 8.9), то выберите JavaScript modules. В ответ на остальные вопросы выберите вариант No, если только не применяете технологию, указанную в вопросе.

Затем появится вопрос: Where does your code run? (Где выполняется ваш код?). Выберите вариант Browser в случае традиционного веб-сайта с кодом JavaScript, выполняемым на стороне клиента (как обычно), или Node, если разрабатываете серверное приложение, которое выполняется на сервере Node.js.

Если вы решите использовать руководство по оформлению кода, то ESLint предложит небольшой список вариантов, и нужно будет выбрать один из них. Затем будут автоматически установлены соответствующие правила с применением одного или нескольких отдельных пакетов — при условии что вы разрешите их установку.

В конце ESLint задаст вопрос: What format do you want your config file to be in? (В каком формате должен быть представлен файл конфигурации?). Все предлагаемые варианты формата подходят одинаково хорошо. Мы предпочитаем использовать JSON из соображений симметрии с файлом package.json, и тогда ESLint сохранит свою конфигурацию в файле .eslintrc.json. Если вы выберете конфигурацию в формате JavaScript, то расширением файла будет .js, а в случае конфигурационного файла в формате YAML — .yaml.

Если выбрать для ESLint режим Check syntax and find problems без подключения дополнительного руководства по оформлению кода, то файл .eslintrc.json будет выглядеть так:

{

    "env": {

        "browser": true,

        "es2021": true

        },

        "extends": "eslint:recommended",

        "parserOptions": {

            "ecmaVersion": 12,

            "sourceType": "module"

        },

        "rules": {

    }

}

Теперь можно запустить ESLint в терминале, чтобы проверить файлы проекта:

npx eslint my-script.js

Но будет гораздо практичнее использовать плагин, который встраивает ESLint в редактор кода. Все редакторы кода, описанные в рецепте 1.1, поддерживают ESLint, а полный список плагинов для поддержки ESLint вы найдете по адресу https://oreil.ly/isQMA.

Для того чтобы подключить ESLint к редактору кода, нужно перейти в биб­лиотеку плагинов этого редактора. Например, в Visual Studio Code для этого нужно щелкнуть на надписи Extensions, расположенной на левой панели, найти в библиотеке плагин eslint и нажать кнопку Install. После того как ESLint будет установлен, следует явно активировать его на странице параметров плагинов (или щелкнуть на значке в виде лампочки, который появится, когда вы откроете в редакторе файл с кодом, и затем выбрать вариант Allow). Иногда имеет смысл установить ESLint глобально, чтобы данный инструмент был доступен для всех проектов на этом компьютере и плагин всегда мог его найти:

$ npm install -g eslint

После того как ESLint будет активирован, вы увидите, что некоторые части кода подчеркнуты волнистой линией. Так ESLint обозначает ошибки и предупреждения. На рис. 1.4 показан пример того, что ESLint обнаружил проблему с оператором switch: выполнение программы «проваливается» к следующему case, чего по умолчанию ESLint не допускает. Метка eslint во всплывающем окне означает, что данное сообщение исходит от плагина ESLint, а не от стандартной системы проверки ошибок VS Code.

Если ESLint не обнаруживает проблем, которые, по идее, должен обнаруживать, возможно, дело в том, что в файле есть другая ошибка — вероятно, даже в другом разделе кода. Попробуйте устранить все остальные проблемы и проверить файл снова.

Рис. 1.4. ESLint обнаружил ошибку в VS Code

Для того чтобы узнать больше о проблеме или попытаться ее исправить, если это возможно, щелкните на надписи Quick Fix или на значке в виде лампочки на рамке окна. Можно также отключить проверку этой проблемы в данной строке или в данном файле, и тогда исправление будет записано в виде отдельного комментария. Например, следующий комментарий отменяет запрет на объявление переменных, которые потом не используются:

/* eslint-disable no-unused-vars */

Если уж пришлось переопределять правила ESLint посредством комментариев, постарайтесь сделать это максимально точно и рационально. Вместо того чтобы отменять проверку всего файла, переопределите правило только для отдельной строки, например, так:

// eslint-disable-next-line no-unused-vars

let futureUseVariable;

или так (заменив eslint-disable-next-line на eslint-disable-line):

let futureUseVariable;    // eslint-disable-line no-unused-vars

Если захотите восстановить проверку данной проблемы, просто удалите комментарий.

Обсуждение

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

ESLint — весьма нетерпимый анализатор: он отмечает даже те проблемы, которые вы можете и не считать таковыми. В число таких проблем входят объявленные, но не используемые переменные; значения параметров, изменяемые внутри функции; пустые блоки условий; регулярные выражения, включающие в себя символы пробелов (и это лишь несколько примеров). Если вы захотите допустить некоторые из этих приемов, то у вас есть возможность переопределить соответствующие параметры в файле конфигурации ESLint или в комментариях к каждой соответствующей строке в каждом файле. Но скорее всего, вы просто измените свой стиль разработки, согласившись с тем, что выбор ESLint позволит избежать проблем в будущем.

ESLint также позволяет автоматически исправлять некоторые виды ошибок и обеспечивать соблюдение стиля оформления, заменяя табуляции пробелами, одиночные кавычки — двойными, поддерживая стили использования скобок, отступов и т.п. Подключив плагин ESLint к редактору кода, такому как VS Code, можно затем настроить этот плагин на автоматическое внесение данных изменений при сохранении файла. Либо можно использовать ESLint только для выявления потенциальных проблем, а для выполнения соглашений об оформлении кода задействовать форматировщик (см. рецепт 1.11).

Если вы работаете в команде, то вам могут просто предоставить готовый файл конфигурации ESLint. Если же нет, то придется самостоятельно решать, какого варианта стандартных правил ESLint придерживаться. Подробнее о рекомендованном наборе правил ESLint (использованном в этом рецепте) читайте здесь: https://eslint.org/docs/rules. В этом документе для каждого условия, проверяемого ESLint, приводятся примеры недопустимого кода. Если же вы захотите применить более строгое руководство по оформлению кода JavaScript, советуем популярный Airbnb JavaScript Style Guide (https://github.com/airbnb/javascript), который устанавливается автоматически с помощью команды eslint -init.

1.11. Согласованное оформление кода с помощью форматировщика

Задача

Соблюдение единого формата для всего кода JavaScript, чтобы сделать его более удобным для чтения и исключить неясности.

Решение

Для автоматического форматирования кода в соответствии с установленными правилами воспользуйтесь форматировщиком кода Prettier. Он обеспечивает согласованность таких деталей оформления, как отступы, одинарные и двойные кавычки, пробелы внутри скобок и между параметрами функций, а также перенос длинных строк кода. Но, в отличие от статического анализатора (см. рецепт 1.10), Prettier не отмечает эти проблемы, чтобы вы их исправили. Вместо этого он применяет правила форматирования автоматически при каждом сохранении кода JavaScript, HTML-страницы или таблицы стилей CSS.

Prettier существует в виде пакета, его можно установить с помощью npm и затем использовать из командной строки. Но гораздо удобнее применять Prettier в виде плагина, подключенного к редактору кода. Плагины Prettier существуют для всех редакторов кода, упомянутых в рецепте 1.1. Большинство этих плагинов размещено на сайте Prettier (https://oreil.ly/weRb5).

Для того чтобы подключить Prettier к редактору кода, перейдите в библиотеку плагинов. Например, в Visual Studio Code для этого нужно нажать кнопку Extensions, расположенную на левой панели, найти в библиотеке плагин prettier и нажать кнопку Install.

Установив Prettier, вы сможете с его помощью редактировать файлы с кодом. Для этого щелкните правой кнопкой мыши в окне редактора рядом с кодом и выберите команду Format Document. Можно настроить свойства плагина, изменив несколько его параметров, таких как максимально допустимая ширина неразделяемой строки кода и выбор символов для отступов — пробелы или табуляция.

В VS Code можно также настроить автоматический запуск Prettier при каждом сохранении файла. Для активации такого поведения выберите команду FilePreferenceSettings, перейдите к Text EditorFormatting section и выберите Format On Save.

Обсуждение

Во многих редакторах кода есть встроенные средства автоматического форматирования, но у отдельного форматировщика кода гораздо больше возможностей. Например, форматировщик Prettier удаляет любое нестандартное форматирование. Он анализирует код и переформатирует его в соответствии с заданными соглашениями, почти не обращая внимания на то, как он был написан изначально. (Из этого правила есть всего два исключения: пустые строки и литералы объектов.) Такой подход гарантирует, что одинаковый код всегда будет представлен одним и тем же способом и код, написанный разными разработчиками, окажется полностью согласованным. Как и для статического анализатора, правила для форматировщика кода определяются в файле конфигурации, а следовательно, их можно легко передать всем членам команды, даже если они используют разные редакторы кода.

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

myFunction(argA(), argB(), argC());

Но если это нецелесообразно, Prettier не просто разорвет код где попало, а выберет наиболее красивое, по его мнению, размещение строк:

myFunction(

    reallyLongArg(),

    omgSoManyParameters(),

    IShouldRefactorThis(),

    isThereSeriouslyAnotherOne()

);

Разумеется, каким бы разумным ни был форматировщик наподобие Prettier, у вас могут быть собственные специфические правила оформления кода. Как говорится, «никому не нравится то, что Prettier делает с его кодом, но всем нравится то, что он делает с кодом его коллег». Другими словами, ценность столь агрессивного и бескомпромиссного форматировщика, как Prettier, состоит в том, что он унифицирует код, написанный разными людьми, чистит код, написанный вашими предшественниками, и сглаживает странные привычки кодирования. Если вы решите использовать Prettier, то получите неограниченную свободу писать код, не задумываясь о расстановке пробелов, разрывах строк или общем виде кода. В итоге он все равно будет приведен к одному и тому же каноническому виду.

Если вы еще не определились, хотите ли задействовать форматировщик кода, или не знаете, как именно настроить его параметры, потратьте некоторое время на эксперименты в интерактивной среде Prettier (https://oreil.ly/TKam1), чтобы понять, как это работает.

Функции статических анализаторов, таких как ESLint, и форматировщиков, таких как Prettier, отчасти перекрываются. Но назначение этих утилит различно, они дополняют друг друга. Если вы решите использовать и ESLint, и Prettier, то вам стоит оставить те правила ESLint, которые выявляют сомнительные стили программирования, но отключить те, которые применяют соглашения о форматировании, такие как правила расстановки отступов, кавычек и пробелов. К счастью, это легко сделать, внеся в ESLint дополнительное правило конфигурации, отменяющее параметры настройки, которые могут вступать в конфликт с правилами Prettier. Самый простой способ сделать это — подключить к проекту пакет eslint-config-prettier:

$ npm install --save-dev eslint-config-prettier

И наконец, нужно внести пакет prettier в раздел extends файла .eslintrc.json. В итоге раздел extends будет представлять собой список, заключенный в квадратные скобки, в конце которого появится prettier, например:

{

    "env": {

            "browser": true,

            "es2021": true

        },

        "extends": ["eslint:recommended", "prettier"],

        "parserOptions": {

            "ecmaVersion": 12,

            "sourceType": "module"

        },

        "rules": {

    }

}

Чтобы ознакомиться с самыми свежими инструкциями по установке пакета eslint-config-prettier, загляните в его документацию (https://oreil.ly/AgxiF).

1.12. Эксперименты в интерактивной среде JavaScript

Задача

Быстро протестировать возможность кодирования или поделиться этой идеей с другими разработчиками, не создавая проект и не запуская автономный редактор кода.

Решение

Нужно воспользоваться интерактивной средой JavaScript. Это сайт, на котором можно редактировать и запускать код JavaScript. Таких интерактивных сред JavaScript существует больше десятка, но в табл. 1.4 приведены пять самых популярных из них.

Таблица 1.4. Интерактивные среды JavaScript

Веб-сайт

Примечания

JSFiddle (https://jsfiddle.net)

Несмотря на то что JSFiddle — едва ли не первая интерактивная среда JavaScript, она по-прежнему сохраняет первенство, обеспечивая симуляцию асинхронных вызовов и интеграцию с GitHub

JS Bin (https://jsbin.com)

Классическая интерактивная среда с простым интерфейсом, состоящим из отдельных вкладок для JavaScript, HTML и CSS, которые можно просматривать поочередно. JS Bin доступна также в виде проекта с открытым кодом

CodePen (https://codepen.io)

Одна из наиболее привлекательно сконструированных интерактивных сред, в которой особое внимание уделено сообществу (самые популярные примеры предлагаются в сообществе CodePen). Ее отшлифованный интерфейс особенно оценят начинающие пользователи

CodeSandbox (http://codesandbox.io)

Одна из самых новых интерактивных сред. Применяет IDE-подобную структуру и очень похожа на онлайн-версию Visual Studio Code

Glitch (https://glitch.com)

Еще одна «IDE в браузере». Интерактивная среда Glitch известна своим плагином для VS Code, который позволяет переключаться между редактированием одного и того же проекта в интерактивной среде в окне браузера и в автономном редакторе

Все эти интерактивные среды JavaScript довольно удобны и функциональны. Все они работают приблизительно одинаково, хотя и выглядят на удивление по-разному. Например, сравним компактный кабинет разработчика в JSFiddle (рис. 1.5) и более свободный редактор в CodePen (рис. 1.6).

Рис. 1.5. Интерактивная среда JavaScript в JSFiddle

Рис. 1.6. То же самое в CodePen

Интерактивную среду JavaScript используют следующим образом. Открыв сайт, можно сразу начать писать код на чистой странице. Несмотря на то что код JavaScript, HTML и CSS находится в отдельных окнах, вам не нужно явно добавлять элемент <script>, чтобы подключить JavaScript, или <link>, чтобы установить связь с CSS. Эти детали уже вставлены в разметку страницы или, что более вероятно, являются неявной частью скрытого шаблона.

Любая интерактивная среда JavaScript позволяет увидеть страницу, над которой вы работаете, рядом с окном кода. Иногда (как в CodePen) окно предварительного просмотра обновляется автоматически, когда вы вносите изменения. В других случаях (как в JSFiddle), чтобы перезагрузить страницу, нужно нажать кнопку Play или Run. Сообщения, которые выводятся с помощью console.log(), в некоторых интерактивных средах JavaScript будут появляться непосредственно в консоли браузера (как в CodePen), а в других — на специальной панели, отображаемой на странице (как в JSFiddle).

Закончив, можете сохранить свою работу. Для этого вы получите специально сгенерированную ссылку, которой можно делиться с другими разработчиками. Но лучше сначала создать учетную запись, чтобы можно было возвращаться к этой среде разработки JavaScript, хранить в ней все образцы кода и редактировать их. (Если сохранить образец кода анонимно, то его потом нельзя будет изменить, хотя можно будет использовать как основу для создания другого образца кода.) Все интерактивные среды, перечисленные в табл. 1.4, позволяют бесплатно создавать учетные записи и сохранять результаты работы.

Точное название образцов кода, которые создаются в интерактивной среде JavaScript, зависит от конкретного сайта. Это может быть fiddle (поделка), pen (набросок), snippet (фрагмент) или еще что-то.

Обсуждение

Интерактивная среда JavaScript — полезная идея, которую подхватили более десятка веб-сайтов. Почти все они имеют следующие общие характеристики.

• Бесплатность. Однако на многих таких сайтах можно подписаться на платные функции, например возможность сохранить работу, но запретить публичный доступ к ней.

• Возможность сохранять работу сколько угодно раз. Это особенно удобно, если вы хотите быстро создать макет с общим доступом или провести совместный эксперимент с другими разработчиками.

• Поддержка множества популярных библиотек и фреймворков JavaScript. Например, к создаваемым примерам можно быстро подключить Lodash, React или jQuery, просто выбрав соответствующий вариант из списка.

• Возможность редактировать HTML, JavaScript и CSS в одном окне. В зависимости от конкретной интерактивной среды оно может быть разделено на несколько одновременно видимых панелей (как в JSFiddle) или между этими панелями нужно переключаться (как в JS Bin). Либо можно выбирать между разными вариантами (как в CodePen).

• Наличие базовых функций автодополнения, проверки ошибок и подсветки синтаксиса (выделение разных элементов кода разными цветами) — пускай и не в том объеме, как в автономных редакторах кода.

• Предварительный просмотр страницы, так что можно легко переключаться между написанием кода и тестированием.

Впрочем, у интерактивных сред JavaScript есть свои ограничения. Например, в них нельзя размещать другие ресурсы, такие как изображения, нельзя взаимодействовать с серверными службами, такими как базы данных, или использовать асинхронные запросы посредством fetch.

Следует также отличать интерактивные среды JavaScript от полноценных облачных сред программирования. Например, с VS Code можно работать онлайн, в полностью размещенной в облаке среде GitHub Codespaces (https://oreil.ly/Vo95d), или AWS Cloud9 от Amazon (https://oreil.ly/tvTZq), или Google Cloud (https://oreil.ly/fqWuW). Ни один из этих продуктов не бесплатен, но все они весьма привлекательны, если вы захотите сформировать специфическую среду разработки, которой можно будет пользоваться через браузер на разных устройствах и не испытывать проблем с настройкой и производительностью.


1 Чтобы использовать консоль разработки в Safari, ее нужно вначале активировать. Для этого выберите в меню команду Safari MenuPreferences, перейдите на вкладку Advanced и установите флажок Show Develop menu in the menu bar.

Таблица 1.2. Сочетания клавиш, чтобы открыть консоль разработки     1

Чтобы использовать консоль разработки в Safari, ее нужно вначале активировать. Для этого выберите в меню команду Safari MenuPreferences, перейдите на вкладку Advanced и установите флажок Show Develop menu in the menu bar.

Глава 2. Строки и регулярные выражения

Продолжая нашу JavaScript-вечеринку, зададим простой вопрос: сколько типов данных поддерживает этот самый популярный в мире язык программирования?

Правильный ответ — восемь. Но, возможно, не те, что вы ожидали. Вот какие восемь типов данных существуют в JavaScript:

Number;

• String;

• Boolean;

• BigInt (для очень больших целых чисел);

• Symbol (для уникальных идентификаторов);

• Object (корневой тип данных для всех остальных типов данных JavaScript);

• undefined (переменная, которой не присвоено значение);

null (отсутствующий объект).

Все рецепты в книге готовятся только из этих ингредиентов. В этой главе мы рассмотрим возможности обработки текста, предоставляемые строками.

2.1. Проверка того, что строка существует и она не пустая

Задача

Перед использованием переменной убедиться, что она определена, является строкой и непустая.

Решение

Прежде чем начинать работу со строкой, часто бывает необходимо убедиться, что применять ее безопасно. Для этого нужно ответить на ряд вопросов.

Чтобы убедиться, что данная переменная является строкой (а не просто переменной, которую можно преобразовать в строку), нужно выполнить следующую проверку:

if (typeof unknownVariable === 'string') {

    // unknownVariable — это строка

}

Для того чтобы убедиться, что строка непустая (не строка вида '', длина которой равна нулю), нужно уточнить нашу проверку:

if (typeof unknownVariable === 'string' && unknownVariable.length > 0) {

    // Это именно строка, и она содержит какие-то символы либо пробелы

}

Для того чтобы отсеять строки, состоящие только из пробелов, можно воспользоваться методом String.trim():

if (typeof unknownVariable === 'string' && unknownVariable.trim().length > 0) {

    // Это именно строка, она непустая и состоит не только из пробелов

}

Порядок проверки условий имеет значение, так как в JavaScript используется сокращенная оценка логических выражений. Это значит, что второе условие (проверка длины) вычисляется только в том случае, если первое условие (проверка типа) истинно. Это важно, поскольку, если unknownVariable является переменной другого типа, например числом, проверка длины закончится неудачей:

// Этот тест безопасен только в том случае, если мы уже знаем,  

// что unknownVariable является строкой

if (unknownVariable.length > 0)

У оператора typeof есть один потенциальный недостаток. Проверку на строковый тип можно обойти, если вместо строкового литерала будет использован объект String:

const unknownVariable = new String('test');

Теперь оператор typeof будет возвращать не string, а object, так как примитив типа string обернут в объект String.

Именно по причинам, подобным этой, в современном JavaScript не рекомендуется создавать экземпляры объекта String. Вместо того чтобы как-то учитывать этот код, лучше исключить подобную практику в любом коде, с которым вы имеете дело. Но если необходимо допустить возможность использования в коде объектов String, проверку нужно усложнить:

if (typeof unknownVariable === 'string' ||

    String.prototype.isPrototypeOf(unknownVariable)) {

    // Это строковый примитив или строка, обернутая в объект

}

В этом коде проверяется выполнение одного из двух условий: является ли переменная строковым примитивом или же объектом, имеющим тот же прототип, что и String2.

Обсуждение

При проверке типов в этом рецепте используется оператор typeof. Он возвращает имя типа переменной в виде строки, состоящей только из строчных букв. Возможны следующие значения:

undefined;

• boolean;

• number;

• bigint;

• string;

• symbol;

• function;

object.

Эти значения соответствуют списку, приведенному в начале главы, но с двумя незначительными различиями. Во-первых, здесь отсутствует null, поскольку вместо строки null такие значения возвращают строку object. (Это часто считают ошибкой языка, но так сложилось по историческим причинам.) Во-вторых, здесь появился еще тип данных function, хотя технически функция — это особый вид объекта.

Время от времени вам будет попадаться следующий старомодный способ валидации строк. Он не требует, чтобы переменная действительно была строкой, а лишь проверяет, что значение может трактоваться как строка и она не будет пустой:

if (unknownVariable) {

    /* Мы попадем сю

...