15 советов по программированию на языке JavaScript

2
19603
Добавить в избранное

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

var против let / const

Помимо var, у нас есть доступ к двум новым идентификаторам для хранения значений: let и const. Давайте посмотрим, чем они отличаются друг от друга.

Пример использования var:

А теперь посмотрите, что происходит, когда мы заменяем var на let:

Переменная, объявленная через let, видна только в рамках блока {...}, в котором объявлена.

Данное изменение в поведении показывает, что нам нужно быть осторожными при оптимизации устаревшего кода с var. Замена var на let может привести к неожиданным последствиям.

Примечание: let и const являются идентификаторами с блочными областями, и когда вы будете ссылаться на идентификаторы до их определения, вы получите ReferenceError.

Лучшая практика: При работе над новой базой кода используйте let для переменных, которые будут изменять свое значение с течением времени, а const для переменных, которые не будут его изменять.

Замена IIFEs блоками

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

А теперь используем блочную область:

Стрелочные функции в языке JavaScript

Часто мы используем вложенные функции, в которых хотели бы сохранить контекст this из его лексической области. Пример показан ниже:

Одним из распространенных решений этой проблемы является сохранение контекста this с помощью использования переменной:

Мы также можем перейти к заданному контексту this:

Привязка контекста:

Используя стрелочные функции, лексическое значение this не меняется. Перепишем код с использованием стрелочных функций:

Лучшая практика: всегда используйте стрелочные функции, когда вам нужно сохранить лексическое значениеthis.

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

Лучшая практика: используйте стрелочные функции вместо выражений функций, если возможно.

Строки в языке JavaScript

С ES6 стандартная библиотека значительно изменилась. Наряду с этими изменениями применяются новые методы, такие как .includes() и  .repeat(), которые можно использовать для строк.

.includes( )

Чтобы обозначить ограничение строки, мы можем просто использовать .includes(), который вернет логическое значение, вместо проверки > -1:

.repeat( )

Теперь у нас есть доступ к реализации:

Литералы шаблонов в языке JavaScript

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

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

Еще проще:

Мы можем задавать новые строки следующим образом:

Или:

Литералы шаблонов сохранят новые строки, не указывая их явно:

Литералы шаблонов также могут принимать выражения:

Деструктуризация

Деструктуризация позволяет нам извлекать значения из массивов или объектов и хранить их в переменных.

Деструктурированные массивы

Деструктурированные объекты

Модули в языке JavaScript

До ES6 мы использовали библиотеки, такие как Browserify, для создания модулей на стороне клиента. С ES6 мы можем напрямую использовать модули всех типов (AMD и CommonJS).

Экспорт в CommonJS

Экспорт в ES6

С ES6 у нас появились различные варианты экспорта. Мы можем выполнять Named Exports:

Экспорт списка объектов:

Мы можем экспортировать функции, объекты и значения с помощью ключевого слова export:

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

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

Импорт

ES6 предоставляет различные варианты импорта. Мы можем импортировать весь файл:

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

Можем переименовать импорт:

Кроме того, мы можем импортировать все вещи (также называемые импортом пространства имен):

Наконец, также можно импортировать список значений из модуля:

Импортирование из биндинга по умолчанию:

Мы можем иногда смешивать импорт по умолчанию и смешанный импорт, если это необходимо:

Или импортировать их следующим образом:

При импорте модуля, экспортированного с использованием синтаксиса commonjs (например, React), можно:

Это также можно упростить, используя:

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

Параметры

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

Параметры по умолчанию

В ES6 можно передать значения по умолчанию для параметров в функции:

Параметры остановки

В ES5 мы обрабатывали неопределенное количество аргументов:

Используя оператор rest, мы можем передавать неопределенное количество аргументов:

Именованные параметры

Одним из шаблонов в ES5 для обработки именованных параметров был шаблон объектов опций, принятый из jQuery.

Можно достичь той же функциональности, используя деструктурирование как формальный параметр для функции:

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

В ES5 мы могли найти максимальные значения в массиве, используя метод apply на Math.max следующим образом:

В ES6 мы используется оператор распространения для передачи массива значений, которые выступают параметрами для функции:

Мы можем легко конкатенировать литералы массивов:

Классы в языке JavaScript

До ES6 мы реализовали классы, создавая функцию-конструктор и добавив свойства:

И создавали расширенные классы следующим образом:

С помощью ES6 мы можем создавать классы таким образом:

И расширять их, используя ключевое слово extends:

Лучшая практика. Хотя ES6 скрывает, как работает реализация и прототипы, это хорошая функция для новичков. Также она позволяет нам писать более чистый код.

Символы в языке JavaScript

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

Symbol( )

Вызов Symbol () или Symbol (описание) создаст уникальный символ, который не может быть просмотрен глобально.

Symbol.for(key)

Symbol.for(key) создает символ, который по-прежнему неизменен и уникален, но может быть просмотрен глобально. Два идентичных вызова Symbol.for(key) возвращают один и тот же символ.

Примечательным примером использования Symbol для взаимодействия является Symbol.iterator, который существует во всех повторяющихся типах в ES6: массивы, строки, генераторы и т. д.

Maps в языке JavaScript

Maps — необходимая структура данных в языке JavaScript. До ES6 мы создавали хэш-карты через объекты:

Однако это не защищает нас от случайных переопределений функций с конкретными именами свойств:

Maps позволяют нам устанавливать, получать и искать значения (и многое другое).

Самая удивительная часть Maps — это то, что мы больше не ограничиваемся использованием строк. Теперь мы можем использовать любой тип в качестве ключа, и он не будет привязан к типу для строки.

Примечание. Использование функций или объектов не будет работать при проверке равенства с использованием таких методов, как map.get(). Таким образом, придерживайтесь примитивных значений, таких как строки, булевы и числа.

Мы также можем перебирать Maps с использованием .entries():

WeakMaps

Чтобы хранить частные версии данных у нас были разные способы сделать это:

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

Самое интересное в использовании WeakMaps для хранения наших личных данных заключается в том, что их ключи не выдают имена свойств, которые можно увидеть с помощью Reflect.ownKeys():

Практичным примером использования WeakMaps является хранение данных, связанных с элементом DOM:

Как показано выше, когда объект уничтожается сборщиком мусора, WeakMap автоматически удаляет пару ключ-значение, которая была идентифицирована этим объектом.

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

Промисы (обещания) в языке JavaScript

Промисы позволяют нам превратить наш горизонтальный код:

В вертикальный:

До ES6 мы использовали bluebird или Q. Теперь у нас есть промисы:

Вот практический пример использования промисов:

Мы также можем распараллелить промисы для обработки массива асинхронных операций с помощью Promise.all ():

Генераторы в языке JavaScript

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

Ниже приведен простой пример использования генераторов:

Мы можем использовать генераторы для записи асинхронного кода синхронно:

Напишем функцию генератора, которая будет возвращать наши данные:

Мы гарантируем, что entry1 будет иметь данные, которые необходимо проанализировать и сохранить в data1.

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

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

Улучшая наш генератор промисами, получаем способ определения ошибок с помощью нашего промиса .catch и reject:

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

Async Await в языке JavaScript

Async Await позволяет выполнять то же самое, что мы выполнили с помощью генераторов и промисов, но с меньшими усилиями:

Геттеры и сеттеры в языке JavaScript

ES6 начал поддерживать функции getter и setter внутри классов. Посмотрим на следующий пример:

Последние браузеры также поддерживают функции getter / setter в объектах, и мы можем использовать их для вычисляемых свойств, добавляя предварительную обработку перед настройкой / получением:

Источник

Интересуетесь веб-разработкой?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Добавить комментарий