11 полезных приёмов в JavaScript

В этой статье мы расскажем об 11 весьма полезных приёмах в языке JavaScript. Они помогут вам сократить объём кода и оптимизировать его. Итак, начнём. 

Конвертация в Boolean при помощи оператора !!

Порой нам нужно проверить, существует ли значение переменной и валидно ли оно, чтобы в этих случаях считать их верными, то есть равными true. Для этого можно применить к переменной оператор двойного отрицания !!, который автоматически меняет любой тип данных на логический (boolean) и возвращает false только в тех случаях, когда переменная принимает одно из следующих значений: 0, null, "", undefined или NaN. Вот простой пример:

function Account(cash) {
    this.cash = cash;
    this.hasMoney = !!cash;
}
var account = new Account(100.50);
console.log(account.cash); // 100.50
console.log(account.hasMoney); // true
var emptyAccount = new Account(0);
console.log(emptyAccount.cash); // 0
console.log(emptyAccount.hasMoney); // false

Если значение account.cash больше нуля, account.hasMoney будет равна true.

Конвертация в Number при помощи оператора +

Удивительно простой приём! Работает он только со строками, а во всех остальных случаях возвращает NaN (Not a Number). Взглянем на пример:

function toNumber(strNumber) {
    return +strNumber;
}
console.log(toNumber("1234")); // 1234
console.log(toNumber("ACB")); // NaN

Эта магия также работает с типом Date, возвращая timestamp:

console.log(+new Date()) // 1461288164385

Раз уж речь зашла о магии, советуем прочитать нашу статью, которая расскажет о настоящей магии JavaScript.

Упрощённая запись условных выражений

Допустим, у нас есть подобный код:

if (connected) {
    login();
}

Его можно сократить, поместим оператор && между переменной (значение которой проверяется) и функцией. Вот так можно записать наш код:

connected && login();

Аналогично можно проверить, есть ли у объекта те или иные атрибуты и методы:

user && user.login();

Это связано с так называемой короткой логикой: если левый операнд && равен false, то правый операнд даже не будет вычислен, потому что и так ясно, что все выражение ложно. И если правым операндом является функция, то она не будет вызвана.

Значения по умолчанию при помощи оператора ||

В ES6 есть возможность задать значение аргумента по умолчанию. Для того, чтобы воспроизвести эту фичу в старых браузерах, можно использовать оператор ||, добавив в качестве второго параметра значение по умолчанию. Если первый параметр вернёт false, будет использоваться второй. Вот пример:

function User(name, age) {
    this.name = name || "Oliver Queen";
    this.age = age || 27;
}
var user1 = new User();
console.log(user1.name); // Oliver Queen
console.log(user1.age); // 27
var user2 = new User("Barry Allen", 25);
console.log(user2.name); // Barry Allen
console.log(user2.age); // 25

Подробнее о стандарте ES6 можно почитать в наших статьях:

Распознавание свойств объекта

Приём очень полезен, когда нужно проверить, существует ли тот или иной атрибут или метод. Также он может пригодиться и при кроссбраузерной вёрстке. Представим, что вам нужно написать код, совместимый с древним Internet Explorer 6, и вы хотите использовать document.querySelector() для получения элементов по идентификаторам. Но в IE6 такой функции не существует, поэтому нужно добавить проверку:

if ('querySelector' in document) {
    document.querySelector("#id");
} else {
    document.getElementById("id");
}

В этом примере мы можем использовать document.getElementById() как запасной вариант, если в объекте-документе нет функции querySelector.

Получение последнего элемента массива

Наверняка вы знакомы с методом Array.prototype.slice(begin, end): с его помощью можно вырезать из массива кусок, задавая его границы begin и end. Если вы не зададите значение end, то функция автоматически задаст максимально возможное значение. Но немногие знают, что этот метод может принимать и отрицательные значения — если begin равен отрицательному числу, вы получите последние элементы массива:

var array = [1,2,3,4,5,6];
console.log(array.slice(-1)); // [6]
console.log(array.slice(-2)); // [5,6]
console.log(array.slice(-3)); // [4,5,6]

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

Этот способ позволяет зафиксировать размер массива и удалить все лишние элементы. Например, у вас есть массив из 10 элементов, а вам нужны только первые 5. В таком случае достаточно одной простой команды: array.length = 5. Вот наглядный пример:

var array = [1,2,3,4,5,6];
console.log(array.length); // 6
array.length = 3;
console.log(array.length); // 3
console.log(array); // [1,2,3]

Замена всех подстрок

Метод String.replace() позволяет заменять подстроки при помощи регулярных выражений, но по умолчанию заменяется лишь первое вхождение подстроки. Тем не менее, вы можете исправить это, добавив /g в конец «регулярки»:

var string = "john john";
console.log(string.replace(/hn/, "ana")); // "joana john"
console.log(string.replace(/hn/g, "ana")); // "joana joana"

Слияние массивов

Если вам нужно объединить два массива, вы можете использовать метод Array.concat():

var array1 = [1,2,3];
var array2 = [4,5,6];
console.log(array1.concat(array2)); // [1,2,3,4,5,6];

Однако он не подходит для слияния больших массивов, поскольку потребляет большое количество памяти, создавая новый массив. В этом случае лучше использовать Array.push.apply(arr1, arr2), что поместит второй массив в первый, сократив потребление памяти:

var array1 = [1,2,3];
var array2 = [4,5,6];
console.log(array1.push.apply(array1, array2)); // [1,2,3,4,5,6];

Конвертация NodeList в массив

Если вы вызовете document.querySelectorAll("p"), то наверняка получите массив элементов DOM, объект класса NodeList. Проблема в том, что у него нет таких полезных методов, как sort(), reduce(), map() и filter(). Чтобы активировать эти и другие полезные методы, вам нужно конвертировать NodeList в массив. Для этого нужно просто выполнить [].slice.call(elements):

var elements = document.querySelectorAll("p"); // NodeList
var arrayElements = [].slice.call(elements); // Теперь NodeList — это массив
var arrayElements = Array.from(elements); // Ещё один способ конвертации

Перемешивание элементов массива

Чтобы перемешать элементы массива, не используя сторонние библиотеки вроде Lodash, можно выполнить этот приём:

var list = [1,2,3];
console.log(list.sort(function() { Math.random() - 0.5 })); // [2,1,3]

Заключение

Вы узнали несколько полезных приёмов, которые позволяют уменьшить JS-код. Многие из них используются в таких библиотеках, как, например, Lodash, Underscore.js и Strings.js. Если вы знаете другие приёмы, делитесь ими, и мы пополним нашу статью.

Перевод статьи «12 Extremely Useful Hacks for JavaScript»