12 приемов работы с JavaScript, которых нет в большинстве туториалов
Когда я начал изучать JavaScript, то первым делом составил список приемов, которые помогали мне экономить время. Я подсмотрел их у других программистов, на разных сайтах и в мануалах.
В этой статье я покажу 12 отличных способов улучшить и ускорить свой JavaScript-код. В большинстве случаев они универсальны.
Напоминаем:для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».
Тип объекта Set был введен в ES6, вместе с …, spread-оператором, мы можем использовать его для создания нового массива, в котором содержатся лишь уникальные значения.
В обычной ситуации для выполнения той же операции нужно гораздо больше кода.
Этот прием работает для массивов, содержащих примитивные типы: undefined, null, boolean, string и number. Если вы работаете с массивом, содержащим объекты, функции или дополнительные массивы, вам понадобится другой подход.
Длина кэш-массива в циклах
ЦИКЛЫ
Когда вы изучаеете for для циклов, то следуете стандартной процедуре:
for (let i = 0; i < array.length; i++){
console.log(i);
}
Тем не менее, при таком синтаксисе цикл for повторно проверяет длину массива при каждой итерации.
Иногда это может быть полезно, но в большинстве случаев эффективнее кэшировать длину массива, что потребует одного обращения к нему. Мы можем сделать это путем определения переменной длины, где задать переменную i, например, так:
for (let i = 0, length = array.length; i < length; i++){
console.log(i);
}
В принципе, почти то же самое, что и выше, но при увеличении размера цикла мы получим значительную экономию времени.
Оценка короткого замыкания (оценка Маккарти)
УСЛОВНЫЕ ОПЕРАТОРЫ
Тернарный оператор — быстрый и эффективный способ написать простые (а иногда и не очень простые) conditional statements:
Но иногда даже тернарный оператор сложнее, чем требуется. Вместо него мы можем использовать ‘and’ && и ‘or’ || логические операторы для оценки некоторых выражений еще более кратким способом. Его часто называют «коротким замыканием» или «оценкой короткого замыкания».
Как это работает
Скажем, мы хотим вернуть только одно из двух или более условий.
Использование && вернет первое false значение. Если каждый операнд оценивается как true, то будет возвращено последнее вычисленное выражение.
let one = 1, two = 2, three = 3;
console.log(one && two && three); // Result: 3
console.log(0 && null); // Result: 0
Использование || позволит вернуть первое true значение. Если каждый операнд оценивается как false, то будет возвращено последнее вычисленное значение.
let one = 1, two = 2, three = 3;
console.log(one || two || three); // Result: 1
console.log(0 || null); // Result: null
Пример 1
Скажем, мы хотим вернуть length переменной, но не знаем ее тип.
В этом случае можно использовать if/else для проверки того, что foo — подходящий тип, но этот способ может оказаться слишком долгим. Поэтому лучше возьмем наше «короткое замыкание».
return (foo || []).length;
Если переменная foo имеет подходящую length, то она и будет возвращена. В противном случае мы получим 0.
Пример 2
Были ли у вас проблемы с доступом к вложенному объекту? Вы можете не знать, существует ли объект или одно из его подсвойств, и это может привести к проблемам.
К примеру, мы хотели получить доступ к свойству data в this.state, но data не определено, пока наша программа не вернет запрос на выборку.
В зависимости от того, где мы его используем, вызов this.state.data может помешать запуску приложения. Чтобы решить проблему, мы могли бы обернуть это в условное выражение:
Более подходящим вариантом будет использование оператора «or».
return (this.state.data || 'Fetching Data');
Мы не можем изменить код выше, чтобы использовать &&. Оператор ‘Fetching Data’ && this.state.data вернет this.state.data независимо от того, является он undefined или нет.
Опциональная цепочка
Можно предложить использовать опциональную цепочку при попытке вернуть свойство глубоко в древовидную структуру. Так, символ знака вопроса? может использоваться для извлечения свойства, только если оно не равно нулю (null).
Например, мы могли бы выполнить рефакторинг примера выше, получив this.state.data?.. (). То есть data возвращается лишь в том случае, если значение не null.
Или, если важно, определено ли state или нет, мы могли бы вернуть this.state?.data.
Преобразование в Boolean
ПРЕОБРАЗОВАНИЕ ТИПОВ
Кроме обычных логических функций true и false, JavaScript также рассматривает все другие значения как truthy или falsy.
Пока не указано иное, все значения в JavaScript — truthy, за исключением 0, «», null, undefined, NaN и, конечно, false. Последние являются falsy.
Мы можем легко переключаться между теми и другими, используя оператор !, который также преобразует тип в логический.
Могут быть ситуации, когда + будет интерпретироваться как оператор конкатенации, а не сложения. Во избежание этого стоит использовать тильды: ~~. Этот оператор эквивалентен выражению -n-1. К примеру, ~ 15 равно -16.
Использование двух тильд подряд сводит на нет операцию, потому что — (- — n — 1) — 1 = n + 1 — 1 = n. Другими словами, ~ -16 равно 15.
Начиная с ES7, можно использовать оператор возведения в степень ** в качестве сокращения для степеней. Это гораздо быстрее, чем использование Math.pow (2, 3). Вроде просто, но в список приемов этот момент включен, поскольку далеко не везде он упоминается.
console.log(2 ** 3); // Result: 8
Не стоит путать его с символом ^, который обычно используется для возведения в степень. Но вот в JavaScript это оператор XOR.
До ES7 сокращение ** можно было применять только для степеней с основанием 2 с использованием оператора побитового сдвига влево <<:
Math.pow(2, n);
2 << (n - 1);
2**n;
К примеру, 2 << 3 = 16 эквивалентно выражению 2 ** 4 = 16.
Float в целое число
ОПЕРАЦИИ / ПРЕОБРАЗОВАНИЕ ТИПОВ
При необходимости преобразовать float в целое число можно воспользоваться Math.floor(), Math.ceil() или Math.round(). Но есть и более быстрый путь, для этого используем |, то есть оператор OR.
Поведение | в значительной степени зависит от того, имеете ли вы дело с положительными или отрицательными числами, поэтому этот способ подходит только в том случае, если вы уверены в том, что делаете.
n | 0 удаляет все, что идет после десятичного разделителя, усекая число с плавающей точкой до целого числа.
Вы можете получить тот же эффект округления, используя ~~. После принудительного преобразования в целое число значение остается неизменным.
Убираем замыкающие числа
Оператор OR можно использовать для того, чтобы убрать любое количество цифр из числа. Это означает, что нам не нужно преобразовывать типы, как здесь:
let str = "1553";
Number(str.substring(0, str.length - 1));
Стрелочные обозначения ES6 можно использовать в методах класса, и при этом подразумевается привязка. Благодаря этому можно попрощаться с повторяющимися выражениями, такими как this.myMethod = this.myMethod.bind (this)!
Возможно, вы уже использовали JSON.stringify. Знаете ли вы, что он помогает форматировать ваш JSON?
Метод stringify () принимает два необязательных параметра: функцию replacer, которую можно использовать для фильтрации отображаемого JSON, и значение space.
console.log(JSON.stringify({ alpha: 'A', beta: 'B' }, null, 't'));
// Result:
// '{
// "alpha": A,
// "beta": B
// }'
Вот и все, надеюсь, что все указанные приемы были полезны. А какие хитрости знаете вы? Напишите их в комментариях.