Давайте разберёмся с массивами (объектами Array), какие у них есть методы и как ими пользоваться.
Как создать массив
let myArray = [];
// эквивалентно:
myArray = new Array();
Если мы не создавали массив, а получили переменную извне, то нужно проверить является ли она массивом.
А также иногда бывает полезно проверить переменную на существование проверив её тип,
чтобы избежать ошибки вроде Uncaught ReferenceError: myArray is not defined:
if (
typeof myArray === 'object' &&
Array.isArray(myArray)
) {
console.log(true);
}
Добавление элементов в массив
Заполнить массив можно при создании:
let myArray = [1, 2, 3];
Либо с помощью метода push:
let myArray = [];
myArray.push(1);
myArray.push(2);
myArray.push(3);
// [1, 2, 3]
// эквивалентно:
myArray = [];
myArray.push(1, 2, 3);
// [1, 2, 3]
Либо с помощью метода unshift. В отличие от метода push, метод unshift добавляет элементы в начало массива:
let myArray = [];
myArray.unshift(3);
myArray.unshift(2);
myArray.unshift(1);
// [1, 2, 3]
// или сделаем то же самое, но короче:
myArray = [];
myArray.unshift(1, 2, 3);
// [1, 2, 3]
А ещё массив можно создать из строки:
let myString = "1,2,3";
let myArray = myString.split(',');
// ["1", "2", "3"]
Методы чтения
Получить элемент можно по индексу:
let myArray = [1, 2, 3];
myArray[0]; // 1
myArray[myArray.length - 1]; // 3
Метод pop возвращает последний элемент массива и удаляет его из массива,
т. о. следующий вызов pop вернёт уже предпоследний элемент и так до самого начала,
а на пустом массиве pop возвращает undefined.
let myArray = [1, 2, 3];
while (myArray.length) {
console.log(myArray.pop());
}
// 3
// 2
// 1
Метод shift работает так же как pop, только возвращает элемент из начала массива.
let myArray = [1, 2, 3];
while (myArray.length) {
console.log(myArray.shift());
}
// 1
// 2
// 3
При этом методы push и pop работают быстрее чем методы shift и unshift,
т. к. методы shift и unshift перестраивают индексы всех элементов.
Размер массива
У массивов есть только одно свойство: length - количество элементов, а точнее последний индекс + 1.
Укоротить или очистить массив можно просто обновив свойство length:
let myArray = [1, 2, 3];
myArray.length = 2;
// [1, 2]
myArray.length = 0;
// []
Если заполнить в массиве индекс больший чем следующий за последним, то в массиве образуются пустые элементы:
let myArray = [1, 2, 3];
myArray[10] = 4;
// [1, 2, 3, empty × 7, 4]
Так работает, из-за того, что массивы созданы для работы с упорядоченными числовыми индексами.
Для остальных случаев лучше подойдёт обычный объект {}.
Изменение элемента
Заменить элемент можно по его индексу:
myArray = [1, 2, 3];
myArray[0] = 'first';
// ["first", 2, 3]
Массив это объект
Поэтому кроме элементов массива в переменной можно хранить любые свойства:
let myArray = [1, 2, 3];
myArray.state = 'new';
myArray.createdAt = new Date();
Перебирающие методы
Обойти элементы массива можно с помощью for:
let myArray = [1, 2, 3];
let index;
for (
index = 0;
index < myArray.length;
index++
) {
console.log(myArray[index]);
}
// 1
// 2
// 3
Или с помощью метода forEach(callback[, thisArg]). Аргумент thisArg (если задан) доступен в callback как this.
let myArray = [1, 2, 3];
myArray.forEach(
(currentValue, index, array) => {
console.log(
'index', index,
'currentValue', currentValue
);
}
);
// index 0 currentValue 1
// index 1 currentValue 2
// index 2 currentValue 3
Метод filter(callback[, thisArg]) возвращает массив, состоящий из прошедших проверку элементов.
let myArray = [1, 2, 3];
myArray.filter(
(currentValue, index, array) => {
return currentValue > 2;
}
);
// [3]
Метод map(callback[, thisArg]) применяет callback к каждому элементу массива.
let myArray = [1, 2, 3];
myArray.map(
(currentValue, index, array) => {
return currentValue * 2;
}
);
// [2, 4, 6]
Метод reduce(callback[, initialValue]) выполняет callback к каждому элементу массива, передавая в callback переменную-аккумулятор (первый аргумент функции callback). Начальное значение переменной-аккумулятора - initialValue.
let myArray = [1, 2, 3];
myArray.reduce(
(previousValue, currentValue, index, array) => {
return previousValue + currentValue;
},
0
);
// 6
Метод reduceRight то же самое что и reduce, только справа-налево.
Проверки
Метод every(callback[, thisArg]) проверяет все элементы с помощью callback, возвращает результат проверки всех элементов.
let myArray = [1, 2, 3];
myArray.every(
(currentValue, index, array) => {
return currentValue > 0;
}
);
// true
myArray.every(
(currentValue, index, array) => {
return currentValue > 2;
}
);
// false
Метод some(callback[, thisArg]) проверяет подходит ли хотя бы один элемент под условие callback.
let myArray = [1, 2, 3];
myArray.some(
(currentValue, index, array) => {
return currentValue > 2;
}
);
// true
myArray.some(
(currentValue, index, array) => {
return currentValue > 3;
}
);
// false
Операции с элементами
Метод splice(start, deleteCount[, item1[, item2[, ...]]]) (не путать со slice) удаляет из массива указанную часть элементов, либо заменяет на новые элементы.
При этом возвращает удалённую часть.
let myArray;
let deletedPart;
myArray = [1, 2, 3, 4, 5];
// начиная с индекса 3
// удаляем все остальные элементы до конца
deletedPart = myArray.splice(3);
console.log(deletedPart);
// [4, 5]
console.log(myArray);
// [1, 2, 3]
myArray = [1, 2, 3, 4, 5];
// начиная с индекса 1 удаляем 2 элемента
deletedPart = myArray.splice(1, 2);
console.log(deletedPart);
// [2, 3]
console.log(myArray);
// [1, 4, 5]
myArray = [1, 2, 3, 4, 5];
// удаляем 2 последних элемента
deletedPart = myArray.splice(-2);
console.log(deletedPart);
// [4, 5]
console.log(myArray);
// [1, 2, 3]
myArray = [1, 2, 3, 4, 5];
// удаляем 1 предпоследний элемент
deletedPart = myArray.splice(-2, 1);
console.log(deletedPart);
// [4]
console.log(myArray);
// [1, 2, 3, 5]
myArray = [1, 2, 3, 4, 5];
// заменить первые 3 элемента на другие
deletedPart = myArray.splice(
0,
3,
'one',
'two',
'three'
);
console.log(deletedPart);
// [1, 2, 3]
console.log(myArray);
// ['one', 'two', 'three', 4, 5]
Метод slice([begin[, end]]) (не путать со splice) возвращает часть от массива, не удаляя её из исходного массива.
let myArray = [1, 2, 3, 4, 5];
// без аргументов вернёт копию массива
myArray.slice();
// [1, 2, 3, 4, 5]
// эквивалентно:
myArray.slice(0);
// [1, 2, 3, 4, 5]
// вернёт первые 2 элемента
myArray.slice(0, 2);
// [1, 2]
// вернёт все кроме последнего элемента
myArray.slice(0, -1);
// [1, 2, 3, 4]
// вернёт последние 2 элемента
myArray.slice(-2);
// [4, 5]
Метод concat(value1[, value2[, ...[, valueN]]]) возвращает исходный массив с добавленными новыми элементами.
let myArray = [1, 2, 3, 4, 5];
myArray.concat([4, 3, 2, 1]);
// [1, 2, 3, 4, 5, 4, 3, 2, 1]
myArray.concat([6, 7], [8], 9);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
Метод copyWithin(target, start[, end = this.length]) копирует элементы массива начиная с start (индекс) заканчивая end (не индекс, а уже номер элемента) в исходный массив начиная с target (индекс).
let myArray = [1, 2, 3, 4, 5];
myArray.copyWithin(1, 2, 3);
// [1, 3, 3, 4, 5]
Метод fill(value, start, end = this.length) заполняет значения с start (индекс) по end (номер) значением value.
let myArray = [1, 2, 3, 4, 5];
myArray.fill(7, 0, 3);
// [7, 7, 7, 4, 5]
Метод flat(depth = 1) поднимает элементы вложенных массивов в исходный массив погружаясь во вложенные массивы на глубину depth.
let myArray = [1, [2], [[3]]];
myArray.flat(); // [1, 2, [3]]
// эквивалентно:
myArray.flat(1); // [1, 2, [3]]
myArray.flat(2); // [1, 2, 3]
Метод flatMap(callback[, thisArg]) выполняет callback к элементам исходного массива, а после этого поднимает элементы вложенных массивов в исходный массив погружаясь во вложенные массивы на глубину 1. Т. о. этот метод объединяет функционал map и flat.
let myArray = [1, 2, 3, [4], [[5]]];
myArray.flatMap(
(currentValue, index, array) => {
if (typeof currentValue === 'number') {
return currentValue * 2;
}
return currentValue;
}
);
// [2, 4, 6, 4, [5]]
Метод reverse меняет порядок элементов на обратный.
let myArray = [1, 2, 3];
myArray.reverse();
// [3, 2, 1]
Метод sort([compareFunction]) сортирует массив. Обновляет исходную переменную, а не только возвращает новый результат.
let myArray = [3, 1, 2];
myArray.sort();
// [1, 2, 3]
myArray.sort((a, b) => {
if (a === b) {
return 0;
}
if (a < b) {
return 1;
}
return -1;
});
// [3, 2, 1]
Поиск
Получить индекс элемента по содержимому можно с помощью метода indexOf(searchElement[, fromIndex = 0]):
let myArray = [1, 2, 3];
myArray.indexOf(1);
// 0
myArray.indexOf(2);
// 1
myArray.indexOf(3);
// 2
myArray.indexOf(4);
// -1 - не найдено
Метод lastIndexOf(searchElement[, fromIndex = this.length]) делает то же самое, что и indexOf, только ищет справа-налево.
Метод find(callback[, thisArg]) возвращает значение первого элемента, для которого callback вернул true. Если callback вернул false для всех элементов, то метод вернёт undefined.
let myArray = [1, 2, 3, 4, 5];
myArray.find(
(currentValue, index, array) => {
return currentValue > 1;
}
);
// 2
Метод findIndex(callback[, thisArg]) возвращает индекс первого элемента, для которого callback вернул true. Если callback вернул false для всех элементов, то метод вернёт -1.
let myArray = ['one', 'two'];
myArray.findIndex(
(currentValue, index, array) => {
return currentValue.indexOf('w') !== -1;
}
);
// 1
Метод includes(value) определяет входит ли в массив значение value.
let myArray = [1, 2, 3];
myArray.includes(3); // true
myArray.includes(4); // false
Преобразование в строку
Метод join([separator = ',']) объединяет массив в строку.
let myArray = [1, 2, 3];
myArray.join();
// '1,2,3'
myArray.join('');
// '123'
myArray.join('test');
// '1test2test3'
Метод toLocaleString возвращает строковое представление массива, разделяя элементы локале-зависимой строкой.
let myArray = [1, 2, 3];
myArray.toLocaleString();
// '1,2,3'
Метод toString возвращает строковое представление массива.
let myArray = [1, 2, 3];
myArray.toString();
// '1,2,3'
Итераторы
Метод entries возвращает итератор.
let myArray = ['one', 'two'];
let myIterator = myArray.entries();
myIterator.next();
// {value: [0, "one"], done: false}
myIterator.next();
// {value: [1, "two"], done: false}
myIterator.next();
// {value: undefined, done: true}
Метод keys возвращает итератор по индексам.
let myArray = ['one', 'two'];
let myIterator = myArray.keys();
myIterator.next();
// {value: 0, done: false}
myIterator.next();
// {value: 1, done: false}
myIterator.next();
// {value: undefined, done: true}
Метод values возвращает итератор по значениям.
let myArray = ['one', 'two'];
let myIterator = myArray.values();
myIterator.next();
// {value: "one", done: false}
myIterator.next();
// {value: "two", done: false}
myIterator.next();
// {value: undefined, done: true}
Поддержка
Для работы методов Array.isArray, indexOf, forEach, map, filter и пр. в древних браузерах
понадобится подключить es5-shim.
Для корректной работы методов copyWithin, entries, fill, find, findIndex, keys, values, indexOf в некоторых браузерах понадобится подключить es6-shim.
Или вместо es5-shim и es6-shim можно подключить @babel/polyfill.