12 JavaScript-трюков, которым не учат новичков

4
19177
Добавить в избранное

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

12 JavaScript-трюков, которым не учат новичков

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

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

4 JavaScript-трюка с массивами

Фильтрация уникальных значений

В стандарте ES6 появился новый тип объектов Set. Скомбинировав его со спред-оператором (...), можно легко получить из старого массива новый, в котором будут только уникальные значения.

До ES6 для решения этой задачи пришлось бы написать гораздо больше кода! А еще Set ускоряет код.

Кэширование длины в цикле

Когда мы изучаем программирование на JavaScript, то во всех туториалах встречаем вот такую стандартную конструкцию цикла for:

Нужно следовать рекомендованному шаблону, ведь так? Но он не совсем оптимален. На каждой итерации цикла длина массива array будет высчитываться заново. Иногда это полезно, но в большинстве случаев эффективнее будет ее кэшировать после первого расчета. Для этого создадим переменную length. Это можно сделать в первой части условия, вместе с определением счетчика цикла:

Лаконичность кода почти не страдает, но при работе с большими массивами он будет работать немного эффективнее.

Укорачивание

Это один из самых известных JavaScript-трюков, но повторить его не помешает.

Чтобы удалить несколько значений из конца массива, необязательно пользоваться методами slice(), splice() или pop(). Просто переопределите свойство length:

Это работает только с массивами, а вот с Set, например, трюк не пройдет.

Получение элементов с конца

В метод slice() можно передать отрицательный параметр, тогда отсчет элементов начнется с конца массива.

3 JavaScript-трюка с преобразованием типов

Преобразование в строку

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

Преобразование в число

Для обратного преобразования снова пригодится вездесущий +.

Булевы значения тоже можно превратить в числа:

В некоторых контекстах + работает как оператор конкатенации, поэтому нужна альтернатива.

Если вы работаете с целыми числами (без дробной части), обратите внимание на оператор ~ (тильда), известный также как «побитовое НЕ». Каждый бит операнда он заменяет на противоположный. Выражение ~n эквивалентно выражению -n-1, например, ~15 = -16.

Если этот оператор получает строку, то преобразует ее в число: ~"15" = -16.

Применение побитового отрицания к результату другой операции побитового отрицания успешно отменяет эффект, то есть возвращает исходное число. Действительно, -(-n-1)-1 = n. Другими словами, ~-16 = 15.

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

Использование этих JavaScript-трюков оправдано только в том случае, если вы хорошо понимаете, на чем основано их действие.

Преобразование в булев тип

Язык программирования JavaScript может рассматривать любое значение с логической точки зрения. Все, что преобразуется в false, называется «falsy» (ложное). Это число 0, пустая строка "", null, undefined, NaN и, конечно же, false. Все остальные значения – истинные («truthy»). На эту концепцию опирается множество JavaScript-трюков.

Оператор логического отрицания ! умеет работать со значениями любого типа. Он конвертирует любое falsy значение в true, а любое truthy – в false. Таким образом, на выходе всегда получается булево значение. Вот JavaScript примеры:

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

Пара математических JavaScript-трюков

Загляните в нашу статью о работе с числами и математическими методами в JS.

Быстрое возведение в степень

Стандарт ES7 предложил нам новый оператор ** для возведения числа в степень.

Это явно короче, чем Math.pow(2, 3).

Вероятно, вы ожидали увидеть здесь более привычный символ ^. Но в JavaScript он уже занят – это побитовое исключающее ИЛИ (XOR).

До ES7 у нас был короткий способ возведения в степень только для числа 2 с помощью побитового оператора левого сдвига <<:

Например, 2 << 3 = 16, и 2 ** 4 = 16.

Быстрое округление

Если нужно сделать дробное число целым, вы используете Math.floor(), Math.ceil() или Math.round() – в зависимости от нужного эффекта. Но есть и более быстрый путь – побитовое ИЛИ.

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

Такого же эффекта можно добиться с помощью других JavaScript-трюков, например, уже знакомого нам двойного оператора побитового отрицания (~~).

Удаление разрядов

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

Три бонусных трюка

Короткие вычисления в одну цепочку

Тернарный оператор предоставляет простой и быстрый способ выполнения простых – а иногда и не очень простых – условных вычислений.

Но иногда даже тернарный оператор чересчур сложен. Если ваш программистский дух жаждет краткости, обратите внимание на логические операторы && и ||.

Как это работает?

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

Оператор && вернет первое же «falsy» значение в цепочке. Если случится чудо, и каждый операнд окажется истинным, будет возвращено последнее выполненное выражение.

Оператор ||, напротив, возвращает первое же «truthy» значение. А если все звенья цепи ложны, вернется вычисленное значение последнего выражения.

JavaScript пример 1

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

Можно использовать конструкцию if/else, чтобы проверить, определена ли переменная foo. Эта запись вполне приемлема, но длинновата. Вот более короткий вариант:

Если переменная foo в логическом контексте ложна (например, это null или undefined), то вместо нее будет подставлен пустой массив как дефолтное значение.

JavaScript пример 2

Знакомы с проблемами доступа к свойствам глубокой вложенности? На любом уровне может не оказаться нужного объекта, и выпадет ошибка.

Допустим, есть объект John, а вы хотели бы узнать имя жены Джона (John.wife.name). Однако очень может быть, Джон не женат, необходимо уточнить этот момент.

5 строк кода это немало для ленивых программистов. Давайте укоротим:

Тут мы скомбинировали два логических оператора. У && приоритет больше, поэтому он всегда выполняется первым. Если у Джона нет жены – или у его жены вдруг почему-то нет имени – возвращаем дефолтное значение.

Новые возможности языка

Проблемы со структурой объектов встречаются очень часто, поэтому было внесено предложение добавить в язык JavaScript «опциональные цепочки» (optional chaining). Они позволяют запрашивать глубоко вложенные свойства, не опасаясь ошибок. Движение по цепочке будет продолжено только в том случае, если текущее свойство не равно null.

Если у брата жены Джона есть собака, то это выражение вернет ее кличку.

Предложение сейчас находится в первой стадии рассмотрения (экспериментальная возможность). Вы можете почитать о нем или попробовать в действии с помощью Babel. Для этого добавьте в файл .babelrc плагин @babel/plugin-proposal-optional-chaining.

Автоматический биндинг в классах

Если при создании методов вы используете стрелочные функции, такие методы неявно привязываются к экземплярам класса! Это позволяет сэкономить несколько строк кода и избавиться от надоевших конструкций вроде this.myMethod = this.myMethod.bind(this).

Если хотите вникнуть в тему глубже, загляните сюда:

Форматирование JSON

Скорее всего, вы неоднократно использовали метод JSON.stringify(). А знаете ли вы, что он может самостоятельно форматировать ваш JSON-код?

stringify() может принимать два необязательных параметра (кроме первого – собственно объекта для сериализации):

  • replacer – функция для преобразования значений и свойств или массив тех свойств, которые должны войти в сериализованный объект.
  • space – число, определяющее количество пробелов перед каждым уровнем вложенности, или строка, которая будет вставлена перед каждым уровнем, например, "\t".

Возможно, вы нашли среди этих советов парочку интересных.

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

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

Оригинал: 12 JavaScript Tricks You Won’t Find in Most Tutorials

Хотите получать больше интересных материалов с доставкой?

Подпишитесь на нашу рассылку:

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




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

  1. Пример ([] && foo).length — неверный, поскольку length всегда будет вызываться от foo

    1. Все верно, исправлено. Спасибо за внимательность 🙂

  2. «На каждой итерации цикла длина массива array будет высчитываться заново»… в JS все яляется объектом, в том числе и массив, а array.length — обычное свойство, которое берется по ссылке. «Высчитывается» оно только при создании массива или изменения его длины, а не при обращении

  3. ([] && foo).length;

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