[Перевод] Полезные методы массивов и объектов в JavaScript

Автор статьи, перевод которой мы сегодня публикуем, говорит, что её идею подсказал ему один из выпусков подкаста Syntax FM, в котором давался обзор полезных методов объектов и массивов в JavaScript. Эти методы помогают разработчикам писать чистый и читабельный код. Их применение снижает потребность в сторонних библиотеках наподобие Lodash.

image

Array.prototype.filter ()


Метод Array.prototype.filter () создаёт новый массив, в который попадают только те элементы исходного массива, которые соответствуют заданному условию.

▍Пример


Создадим на основе массива, содержащего сведения о студентах, новый массив, в который попадут записи только о тех студентах, возраст которых позволяет им покупать спиртные напитки.

const studentsAge = [17, 16, 18, 19, 21, 17];
const ableToDrink = studentsAge.filter( age => age > 18 );
// Массив ableToDrink будет содержать два значения: [19, 21]


Array.prototype.map ()


Метод Array.prototype.map () позволяет создать новый массив, основанный на каким-то образом обработанных значениях другого массива. Этот метод отлично подходит для модификации данных, он, благодаря тому, что не вносит изменений в исходный массив, часто используется в React.

▍Пример


Создадим, на основе числового массива, новый массив, в начале каждого элемента которого будет помещён знак $.

const numbers = [2, 3, 4, 5];
const dollars = numbers.map( number => '$' + number);
// Вот как будет выглядеть массив dollars: ['$2', '$3', '$4', '$5']


Array.prototype.reduce ()


Метод Array.prototype.reduce () нередко незаслуженно обходят вниманием. Он позволяет свести массив к единственному значению, накапливаемому в элементе-приёмнике. Значение, возвращаемое этим методом, может быть любого типа. Например, это может быть объект, массив, строка или число.

▍Пример


Воспользуемся методом .reduce() для того, чтобы получить сумму элементов числового массива.

const numbers = [5, 10, 15];
const total = numbers.reduce( (accumulator, currentValue) => accumulator + currentValue);
// в константу total будет записано число 30


На самом деле, этот метод можно использовать множеством интереснейших способов. Соответствующие примеры можно найти в документации MDN. В частности, речь идёт о разворачивании массивов, состоящих из массивов, о группировке объектов по свойствам, и об удалении из массивов повторяющихся элементов.

Array.prototype.forEach ()


Метод Array.prototype.forEach () применяет переданную ему функцию к каждому элементу массива.

▍Пример


Вот как вывести каждый элемент массива в консоль с помощью метода .forEach().

const emotions = ['happy', 'sad', 'angry'];
emotions.forEach( emotion => console.log(emotion) );
// Выведено будет следующее:
// 'happy'
// 'sad'
// 'angry'


Array.prototype.some ()


Метод Array.prototype.some () проверяет, соответствует ли хотя бы один элемент массива условию, задаваемому передаваемой ему функцией. Этот метод, например, способен хорошо показать себя в решении задачи проверки полномочий пользователя. Его можно рассматривать в качестве аналога ранее рассмотренного .forEach(), с той разницей, что, при его применении, с помощью функции, которая ему передана, можно выполнять над элементами массива некие действия до тех пор, пока эта функция не вернёт истинное значение, после чего — прервать обработку.

▍Пример


Проверим, имеется ли в массиве как минимум одна строка admin.

const userPrivileges = ['user', 'user', 'user', 'admin'];
const containsAdmin = userPrivileges.some( element => element === 'admin');
// в containsAdmin будет записано true


Array.prototype.every ()


Метод Array.prototype.every () похож на вышеописанный метод .some(), но он возвращает true только в том случае, если все элементы массива соответствуют условию, задаваемому передаваемой этому методу функцией.

▍Пример


Проверим, все ли оценки, хранящиеся в массиве, равны или больше чем 3.

const ratings = [3, 5, 4, 3, 5];
const goodOverallRating = ratings.every( rating => rating >= 3 );
//goodOverallRating будет равно true


Array.prototype.includes ()


Метод Array.prototype.includes () позволяет узнать, содержит ли массив заданное значение. Он похож на метод .some(), но он проверяет не соответствие элементов массива некоему условию, а наличие в массиве заданного при его вызове значения.

▍Пример


Проверим, имеется ли в массиве строковой элемент waldo:

const names = ['sophie', 'george', 'waldo', 'stephen', 'henry'];
const includesWaldo = names.includes('waldo');
// includesWaldo получит значение true


Array.from ()


Статический метод Array.from () позволяет создавать массивы на основании других массивов или строк. Этому методу, при необходимости, можно передать функцию для выполнения мэппинга, что позволяет воздействовать на данные, которые попадут в новый массив. На самом деле, для выполнения мэппинга предусмотрен особый метод — Array.prototype.map (), поэтому не вполне понятно, зачем кому-то может понадобиться эта возможность метода Array.from().

▍Пример


Создадим массив на основе строки.

const newArray = Array.from('hello');
//массив newArray будет иметь вид ['h', 'e', 'l', 'l', 'o']


Создадим массив, содержащий удвоенные значения элементов исходного числового массива.

const doubledValues = Array.from([2, 4, 6], number => number * 2);
// в массив doubleValues будут записаны следующие данные: [4, 8, 12]


Object.values ()


Метод Object.values () возвращает массив значений свойств переданного ему объекта.

▍Пример


Сформируем массив из значений свойств объекта.

const icecreamColors = {
    chocolate: 'brown',
    vanilla: 'white',
    strawberry: 'red',
}

const colors = Object.values(icecreamColors);
// массив colors будет иметь вид ["brown", "white", "red"]


Object.keys ()


Метод Object.keys () возвращает массив, состоящий из имён свойств объекта (ключей).

▍Пример


Сформируем массив из имён свойств объекта.

const icecreamColors = {
  chocolate: 'brown',
  vanilla: 'white',
  strawberry: 'red',
}

const types = Object.keys(icecreamColors);
//вот как будет выглядеть массив types: ["chocolate", "vanilla", "strawberry"]


Object.entries ()


Метод Object.entries () возвращает, обработав переданный ему объект, массив, содержащий массивы, представляющие собой пары вида [ключ, значение], представляющие собой имена свойств и значения этих свойств.

▍Пример


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

const weather = {
  rain: 0,
  temperature: 24,
  humidity: 33,
}

const entries = Object.entries(weather);
// в массив entries попадут следующие данные
// [['rain', 0], ['temperature', 24], ['humidity', 33]]


Оператор расширения и массивы


Оператор расширения (spread operator, …), в применении к массивам, позволяет разворачивать их, извлекая из них их элементы. Этот оператор полезен, например, при необходимости выполнения объединения нескольких массивов. Кроме того, его использование позволяет избавиться от необходимости использовать метод .splice() в том случае, если нужно удалить из массива какие-то элементы, так как он может быть скомбинирован с методом .slice(), что позволяет избежать изменения исходного массива.

▍Пример


Объединим два массива.

const spreadableOne = [1, 2, 3, 4];
const spreadableTwo = [5, 6, 7, 8];

const combined = [...spreadableOne, ...spreadableTwo];
// массив combined будет выглядеть так: [1, 2, 3, 4, 5, 6, 7, 8]


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

const animals = ['squirrel', 'bear', 'deer', 'salmon', 'rat'];
const mammals = [...animals.slice(0,3), ...animals.slice(4)];
//массив mammals примет следующий вид: ['squirrel', 'bear', 'deer', 'rat']


Оператор расширения и объекты


Применение оператора расширения к объектам позволяет добавлять к ним новые свойства и значения без изменения исходных объектов (то есть, в результате подобных операций создаются новые объекты). Кроме того, этот оператор можно использовать для объединения объектов. Тут стоит отметить, что оператор расширения, применённый к объекту, не воздействует на объекты, вложенные в него.

▍Пример


Создадим новый объект, добавив к исходному объекту новое свойство, не меняя при этом исходный объект.

const spreadableObject = {
  name: 'Robert',
  phone: 'iPhone'
};

const newObject = {
  ...spreadableObject,
  carModel: 'Volkswagen'
}
// объект newObject будет выглядеть так:
// { carModel: 'Volkswagen', name: 'Robert', phone: 'iPhone' }


Синтаксис оставшихся параметров функции


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

▍Пример


Выведем массив, содержащий аргументы, переданные функции.

function displayArgumentsArray(...theArguments) {
  console.log(theArguments);
}

displayArgumentsArray('hi', 'there', 'bud');
// В консоли будет выведен массив ['hi', 'there', 'bud']


Object.freeze ()


Метод Object.freeze () «замораживает» объект, предотвращая изменение существующих свойств этого объекта или добавление новых свойств и значений в объект. Существует ошибочное мнение, что этот метод аналогичен объявлению объектов с использованием ключевого слова const, однако, объекты-константы модифицировать можно.

▍Пример


«Заморозим» объект, после чего попытаемся изменить его свойство и убедимся в том, что сделать этого нельзя.

const frozenObject = {
  name: 'Robert'
}

Object.freeze(frozenObject);

frozenObject.name = 'Henry';
// объект frozenObject не изменится, он сохранится в виде { name: 'Robert' }


Object.seal ()


Метод Object.seal () позволяет «запечатать» объект, предотвратив добавление новых свойств. При этом существующие свойства можно менять.

▍Пример


«Запечатаем» объект, что не позволит добавить в него новое свойство, но оставит возможность менять существующие свойства.

const sealedObject = {
  name: 'Robert'
}

Object.seal(sealedObject);

sealedObject.name = 'Bob';
sealedObject.wearsWatch = true;
// объект sealedObject будет выглядеть так: { name: 'Bob' }


Object.assign ()


Метод Object.assign () позволяет объединять объекты, копируя свойства из одного объекта в другой. На самом деле, того же эффекта можно достичь с помощью вышеописанного оператора расширения, поэтому без этого метода вполне можно обойтись. Надо отметить, что этот метод, как и оператор расширения, не выполняет глубокого клонирования объектов. Если вам нужно готовое средство для глубокого клонирования объектов — взгляните на инструменты библиотеки Lodash.

▍Пример


Создадим из двух объектов один.

const firstObject = {
  firstName: 'Robert'
}

const secondObject = {
  lastName: 'Cooper'
}

const combinedObject = Object.assign(firstObject, secondObject);
// вот как будет выглядеть объект combinedObjec : { firstName: 'Robert', lastName: 'Cooper' }


Итоги


В этом материале мы рассказали о полезных методах массивов и объектов в JavaScript. Многие рассмотренные здесь методы возвращают новые массивы или объекты. Это даёт возможность комбинировать их, объединяя в цепочки. Эти методы не модифицируют исходные данные, что особенно важно в React-разработке. Кроме того, использование этих методов, в подавляющем большинстве случаев, позволяет отказаться от циклов вроде for и while.

Уважаемые читатели! Какими методами массивов и объектов в JavaScript вы пользуетесь чаще всего?

1ba550d25e8846ce8805de564da6aa63.png

© Habrahabr.ru