Хочу поделиться парой Яваскрипт‑приёмов более лаконичного и изящного решения типовых задач. Для наглядности в каждом случае сначала покажу распространённые варианты решения таких задач «в лоб».
Тут не будет хитроумных хаков и приёмов тёмных джедаев Явакрипта, неочевидных простым смертным. Только невинные хитрости на основе базовых возможностей языка. Если вам интересна тёмная сторона силы — напишите в коментах, сделаю выпуск вредных советов :‑)
Важное предостережение: выбирая между понятностью и краткостью, всегда выбирайте понятность. Хоть я и собрал здесь невинные приёмы, в каких‑то случаях они могут навредить. Перед использованием трезво оцените свой уровень и уровень других разработчиков в команде. Все должны понимать, как работает приём под капотом, а не использовать его как заклинание.
Выбор первого существующего значения с помощью оператора «или»
Логический оператор || вернёт первое слева направо значение, которое при приведении к булевому даст true
. Обычно это значит, что вернётся первое существующее значение из списка. Удобно для перебора возможных значений или для установки значений по умолчанию.
Было 👎let userPic = PLACEHOLDER_SRC if (user.gravatarSrc) userPic = user.gravatarSrc if (user.photoSrc) userPic = user.photoSrc
Стало 👍const userPic = user.photoSrc || user.gravatarSrc || PLACEHOLDER_SRC
Фильтрация пустых элементов массива примитивом Boolean
Массивов с пустыми элементами лучше не допускать в коде в принципе, но если уж так сложилось — используйте filter
и передайте в качестве фильтрующей функции примитив Boolean
, это отфильтрует undefined
и null
. Имейте в виду, что Boolean
также отфильтрует NaN
, нули и пустые строки.
Было 🥶const uglyData = [{ … }, undefined, { … }, { … }, undefined] const filteredData = [] uglyData.forEach(item => { if (!!item) filteredData.push(item) })
Стало 🔥const uglyData = [{ … }, undefined, { … }, { … }, undefined] const filteredData = uglyData.filter(Boolean)
Добавление свойств объекту при соблюдении условия через спред‑ и тернарный операторы
Спред‑оператор — удобный способ расширять объекты свойствами других объектов. Если добавить немного хакерства с тернарным оператором, можно расширять объект при выполнении условия. Если условие выполняется — используем для расширения нужный объект. Если нет, используем пустой объект, то есть ничего не меняем.
Было 🥸const userData = { id: …, name: …, locale: … } const analyticData = { deviceId: …, fingerprint: …, abGroup: … } const fullUserData = userData if (needsAnalyticData) { fullUserData.deviceId = analyticData.deviceId fullUserData.fingerprint = analyticData.fingerprint fullUserData.abGroup = analyticData.abGroup }
Стало 😎const userData = { id: …, name: …, locale: … } const analyticData = { deviceId: …, fingerprint: …, abGroup: … } const fullUserData = { ...userData, ...(needsAnalyticData ? analyticData : {}), }
Лаконичный возврат значений для небольших функций
Одна из фишек стрелочной функции — возможность возвращать значение без использования слова return
. Для этого возвращаемое значение должно идти сразу после стрелки, без фигурных скобок. Экономит кучу места в однострочных простых функциях.
Было 👉👈function isProduction() { return window.__MODE__ === 'production' }
Стало 💪const isProduction = () => window.__MODE__ === 'production'
Проверка соответствия условию хотя бы одного или сразу всех элементов массива с помощью some и every
Методы массива some
или every
возвращают true
, когда один или все элементы массива соответствуют условию.
Было 🐢let isAnyCardAvailable = false cards.forEach(card => { if (card.isAvailable) isAnyCardAvailable = true }) let isEveryDebtPayed = false const payedDebts = 0 debts.forEach(debt => { if (debt.isPayed) payedDebts++ }) if (payedDebts === debts.length) isEveryDebtPayed = true
Стало 🚀const isAnyCardAvailable = cards.some(card => card.isAvailable) const isEveryDebtPayed = debts.every(debt => debt.isPayed)
В конце ещё раз напоминаю: между понятностью и краткостью всегда выбирайте понятность. Если приём непонятен вам или вашей команде, не используйте его.
P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.