Array
=====

Объект **`Array`**, как и массивы в других языках программирования, позволяет хранить коллекцию из нескольких элементов под одним именем переменной и имеет методы для выполнения общих операций с массивами.

Описание
--------

Массивы являются спископодобными объектами, чьи прототипы содержат методы для операций обхода и изменения массива. Ни размер JavaScript-массива, ни типы его элементов не являются фиксированными. Поскольку размер массива может увеличиваться и уменьшаться в любое время, то нет гарантии, что массив окажется плотным. То есть, при работе с массивом может возникнуть ситуация, что элемент массива, к которому вы обратитесь, будет пустым и вернёт `undefined`. В целом, это удобная характеристика; но если эта особенность массива не желательна в вашем специфическом случае, вы можете рассмотреть возможность использования типизированных массивов.

Некоторые полагают, что вы не должны использовать массив в качестве ассоциативного массива. В любом случае, вместо него вы можете использовать простые `объекты`, хотя у них есть и свои подводные камни. Смотрите пост Легковесные JavaScript-словари с произвольными ключами*(англ.)* в качестве примера.

### Доступ к элементам массива

Массивы в JavaScript индексируются с нуля: первый элемент массива имеет индекс, равный `0`, а индекс последнего элемента равен значению свойства массива `length` минус 1.


```js
const arr = ["первый элемент", "второй элемент", "последний элемент"];
console.log(arr[0]); // напечатает 'первый элемент'
console.log(arr[1]); // напечатает 'второй элемент'
console.log(arr[arr.length - 1]); // напечатает 'последний элемент'
```


Элементы массива являются свойствами, точно такими же, как, например, свойство `toString`, однако попытка получить элемент массива по имени его свойства приведёт к синтаксической ошибке, поскольку имя свойства не является допустимым именем JavaScript:


```js
console.log(arr.0); // синтаксическая ошибка
```


Это не особенность массивов или их свойств. В JavaScript к свойствам, начинающимся с цифры, невозможно обратиться посредством точечной нотации; к ним можно обратиться только с помощью скобочной нотации. Например, если у вас есть объект со свойством, названным `'3d'`, вы сможете обратиться к нему только посредством скобочной нотации. Примеры:


```js
const years = [1950, 1960, 1970, 1980, 1990, 2000, 2010];
console.log(years.0);   // синтаксическая ошибка
console.log(years[0]);  // работает как положено
```



```js
renderer.3d.setTexture(model, 'character.png');     // синтаксическая ошибка
renderer['3d'].setTexture(model, 'character.png');  // работает как положено
```


Обратите внимание, что во втором примере `3d` заключено в кавычки: `'3d'`. Индексы можно заключать в кавычки (например `years['2']` вместо `years[2]`), но в этом нет необходимости. Значение 2 в выражении `years[2]` будет неявно приведено к строке движком JavaScript через метод преобразования `toString`. Именно по этой причине ключи `'2'` и `'02'` будут ссылаться на два разных элемента в объекте `years` и следующий пример выведет `true`:


```js
console.log(years["2"] != years["02"]);
```


Аналогично, к свойствам объекта, являющимся зарезервированными словами(!) можно получить доступ только посредством скобочной нотации:


```js
const promise = {
  var: "text",
  array: [1, 2, 3, 4],
};

console.log(promise["array"]);
```

### Взаимосвязь свойства `length` с числовыми свойствами

Свойство массивов `length` взаимосвязано с числовыми свойствами. Некоторые встроенные методы массива (например, `join`, `slice`, `indexOf` и т.д.) учитывают значение свойства `length` при своём вызове. Другие методы (например, `push`, `splice` и т.д.) в результате своей работы также обновляют свойство `length` массива.


```js
const fruits = [];
fruits.push("банан", "яблоко", "персик");

console.log(fruits.length); // 3
```


При установке свойства в массиве, если свойство имеет действительный индекс и этот индекс выходит за пределы текущих границ массива, движок соответствующим образом обновит свойство `length`:


```js
fruits[5] = "манго";
console.log(fruits[5]); // 'манго'
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 6
```


Увеличиваем свойство `length`


```js
fruits.length = 10;
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 10
```


Однако, уменьшение свойства `length` приведёт к удалению элементов.


```js
fruits.length = 2;
console.log(Object.keys(fruits)); // ['0', '1']
console.log(fruits.length); // 2
```


Более подробно эта тема освещена на странице, посвящённой свойству `Array.length`.

### Создание массива с использованием результата сопоставления

Результатом сопоставления регулярного выражения строке является JavaScript-массив. Этот массив имеет свойства и элементы, предоставляющие информацию о сопоставлении. Подобные массивы возвращаются методами `RegExp.exec`, `String.match` и `String.replace`. Чтобы было проще понять, откуда и какие появились свойства и элементы, посмотрите следующий пример и обратитесь к таблице ниже:


```js
// Сопоставляется с одним символом d, за которым следует один
// или более символов b, за которыми следует один символ d
// Запоминаются сопоставившиеся символы b и следующий за ними символ d
// Регистр игнорируется

const myRe = /d(b+)(d)/i;
const myArray = myRe.exec("cdbBdbsbz");
```


Свойства и элементы, возвращаемые из данного сопоставления, описаны ниже:

| Свойство/Элемент | Описание | Пример |
| --- | --- | --- |
| `input` | Свойство только для чтения, отражающее оригинальную строку, с которой сопоставлялось регулярное выражение. | cdbBdbsbz |
| `index` | Свойство только для чтения, являющееся индексом (отсчёт начинается с нуля) в строке, с которого началось сопоставление. | 1 |
| `[0]` | Элемент только для чтения, определяющий последние сопоставившиеся символы. | dbBd |
| `[1], ...[n]` | Элементы только для чтения, определяющие сопоставившиеся подстроки, заключённые в круглые скобки, если те включены в регулярное выражение. Количество возможных подстрок не ограничено. | [1]: bB [2]: d |

Конструктор
-----------

`Array()` (en-US)

Создаёт новый объект `Array`.

Статические свойства
--------------------

`Array[@@species]`

Возвращает конструктор `Array`.

Статические методы
------------------

`Array.from()`

Создаёт новый экземпляр `Array` из итерируемого или массивоподобного объекта.

`Array.fromAsync()` (en-US)

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

`Array.isArray()`

Возвращает `true` если аргумент является массивом и `false` в противном случае.

`Array.of()`

Создаёт новый экземпляр `Array` с переменным количеством аргументов, независимо от количества или типа аргументов.

Свойства экземпляра
-------------------

Эти свойства определены в `Array.prototype` и есть у всех экземпляров `Array`.

`Array.prototype.constructor`

Функция-конструктор, создающая экземпляр объекта. Для экземпляров `Array` начальным значением является конструктор `Array` (en-US).

`Array.prototype[@@unscopables]`

Содержит имена свойств, которые не включены в стандарт ECMAScript до версии ES2015 и которые игнорируются оператором `with`.

Собственные свойства каждого экземпляра `Array`:

`length`

Отражает количество элементов в массиве.

Методы экземпляра
-----------------

`Array.prototype.at()`

Возвращает элемент массива с указанным индексом. Принимает отрицательные значения, для которых отсчёт идёт с конца массива.

`Array.prototype.concat()`

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

`Array.prototype.copyWithin()`

Копирует последовательность элементов внутри массива.

`Array.prototype.entries()`

Возвращает новый объект *array iterator*, который содержит пары ключ/значение для каждого индекса в массиве.

`Array.prototype.every()`

Возвращает `true` если для каждого элемента массива переданная в качестве аргумента функция возвращает `true`.

`Array.prototype.fill()`

Заполняет все элементы массива от начального индекса до последнего указанным значением.

`Array.prototype.filter()`

Возвращает новый массив, содержащий все элементы исходного массива, для которых переданная функция вернула `true`.

`Array.prototype.find()`

Возвращает значение первого элемента массива, для которого переданная в качестве аргумента функция возвращает `true`, или `undefined` если таких элементов нет.

`Array.prototype.findIndex()`

Возвращает индекс первого элемента массива, для которого переданная в качестве аргумента функция возвращает `true`, или `-1` если таких элементов нет.

`Array.prototype.findLast()` (en-US)

Возвращает значение последнего элемента массива, для которого переданная в качестве аргумента функция возвращает `true`, или `undefined` если таких элементов нет.

`Array.prototype.findLastIndex()` (en-US)

Возвращает индекс последнего элемента массива, для которого переданная в качестве аргумента функция возвращает `true`, или `-1` если таких элементов нет.

`Array.prototype.flat()`

Возвращает новый массив, содержащий элементы всех вложенных массивов до указанной глубины.

`Array.prototype.flatMap()`

Возвращает новый массив, сформированный вызовом переданной функции с каждым элементом, а затем «уплощённый» на один уровень.

`Array.prototype.forEach()`

Вызывает функцию для каждого элемента массива.

`Array.prototype.includes()`

Возвращает `true`, если массив содержит переданное значение и `false` в противном случае.

`Array.prototype.indexOf()`

Возвращает первый (наименьший) индекс, по которому может быть найден переданный элемент.

`Array.prototype.join()`

Объединяет все элементы массива в строку.

`Array.prototype.keys()`

Возвращает новый объект *array iterator*, который содержит ключи каждого индекса массива.

`Array.prototype.lastIndexOf()`

Возвращает последний (наибольший) индекс, по которому может быть найден переданный элемент или `-1` если таких элементов нет.

`Array.prototype.map()`

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

`Array.prototype.pop()`

Удаляет последний элемент массива и возвращает его значение.

`Array.prototype.push()`

Добавляет один или более элементов в конец массива и возвращает новое значение `length` массива.

`Array.prototype.reduce()`

Вызывает указанную функцию-редьюсер для каждого элемента массива (слева направо) для получения единственного значения.

`Array.prototype.reduceRight()`

Вызывает указанную функцию-редьюсер для каждого элемента массива (справа налево) для получения единственного значения.

`Array.prototype.reverse()`

Изменяет порядок элементов массива *на месте* (то есть изменяя исходный массив) на обратный (первый станет последним, последний — первым).

`Array.prototype.shift()`

Удаляет первый элемент массива и возвращает его значение.

`Array.prototype.slice()`

Извлекает часть массива и возвращает её в виде нового массива.

`Array.prototype.some()`

Возвращает `true` если хотя бы для одного элемента массива переданная в качестве аргумента функция возвращает `true`.

`Array.prototype.sort()`

Сортирует элементы массива *на месте* (то есть изменяя исходный массив) и возвращает массив.

`Array.prototype.splice()`

Добавляет и/или удаляет элементы массива.

`Array.prototype.toLocaleString()`

Возвращает локализованную строку, представляющую исходный массив и его элементы. Переопределяет метод `Object.prototype.toLocaleString()`.

`Array.prototype.toReversed()` (en-US)

Возвращает новый массив с элементами в обратном порядке без изменения исходного массива.

`Array.prototype.toSorted()` (en-US)

Возвращает новый массив с отсортированными по возрастанию элементами без изменения исходного массива.

`Array.prototype.toSpliced()` (en-US)

Возвращает новый массив с удалёнными и/или заменёнными элементами без изменения исходного массива.

`Array.prototype.toString()`

Возвращает строку, представляющую исходный массив и его элементы. Переопределяет метод `Object.prototype.toString()`.

`Array.prototype.unshift()`

Добавляет один или более элементов в начало массива и возвращает новое значение `length` массива.

`Array.prototype.values()`

Возвращает новый объект *array iterator*, который содержит значения каждого индекса массива.

`Array.prototype.with()` (en-US)

Возвращает новый массив с заменённым значением элемента с указанным индексом без изменения исходного массива.

`Array.prototype[@@iterator]()`

Псевдоним метода `values()`.

Примеры
-------

### Пример: создание массива

Следующий пример создаёт массив `msgArray` с длиной 0, присваивает значения элементам `msgArray[0]` и `msgArray[99]`, что изменяет длину массива на 100.


```js
const msgArray = [];
msgArray[0] = "Привет";
msgArray[99] = "мир";

if (msgArray.length === 100) {
  console.log("Длина равна 100.");
}
```

### Создание массива


```js
const fruits = ["Яблоко", "Банан"];

console.log(fruits.length);
// 2
```

### Доступ к элементу массива по индексу


```js
const first = fruits[0];
// Яблоко

const last = fruits[fruits.length - 1];
// Банан
```

### Итерирование по массиву


```js
fruits.forEach(function (item, index, array) {
  console.log(item, index);
});
// Яблоко 0
// Банан 1
```

### Добавление элемента в конец массива


```js
const newLength = fruits.push("Апельсин");
// ["Яблоко", "Банан", "Апельсин"]
```

### Удаление последнего элемента массива


```js
const last = fruits.pop(); // удалим Апельсин (из конца)
// ["Яблоко", "Банан"];
```

### Удаление первого элемента массива


```js
const first = fruits.shift(); // удалим Яблоко (из начала)
// ["Банан"];
```

### Добавление элемента в начало массива


```js
const newLength = fruits.unshift("Клубника"); // добавляет в начало
// ["Клубника", "Банан"];
```

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


```js
fruits.push("Манго");
// ["Клубника", "Банан", "Манго"]

const pos = fruits.indexOf("Банан");
// 1
```

### Удаление элемента с определённым индексом


```js
const removedItem = fruits.splice(pos, 1); // так можно удалить элемент

// ["Клубника", "Манго"]
```

### Удаление нескольких элементов, начиная с определённого индекса


```js
const vegetables = ["Капуста", "Репа", "Редиска", "Морковка"];
console.log(vegetables);
// ["Капуста", "Репа", "Редиска", "Морковка"]

const start = 1;
const deleteCount = 2;

const removedItems = vegetables.splice(start, deleteCount);
// так можно удалить элементы, deleteCount определяет количество элементов для удаления,
// начиная с позиции(pos) и далее в направлении конца массива.

console.log(vegetables);
// ["Капуста", "Морковка"] (исходный массив изменён)

console.log(removedItems);
// ["Репа", "Редиска"]
```

### Создание копии массива


```js
const shallowCopy = fruits.slice(); // так можно создать копию массива
// ["Клубника", "Манго"]
```

### Пример: создание двумерного массива

Следующий код создаёт шахматную доску в виде двумерного массива строк. Затем он перемещает пешку путём копирования символа 'p' в позиции (6,4) на позицию (4,4). Старая позиция (6,4) затирается пустым местом.


```js
const board = [
  ["R", "N", "B", "Q", "K", "B", "N", "R"],
  ["P", "P", "P", "P", "P", "P", "P", "P"],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  [" ", " ", " ", " ", " ", " ", " ", " "],
  ["p", "p", "p", "p", "p", "p", "p", "p"],
  ["r", "n", "b", "q", "k", "b", "n", "r"],
];

console.log(board.join("\n") + "\n\n");

// Двигаем королевскую пешку вперёд на две клетки
board[4][4] = board[6][4];
board[6][4] = " ";
console.log(board.join("\n"));
```


Ниже показан вывод:
```

R,N,B,Q,K,B,N,R
P,P,P,P,P,P,P,P
 , , , , , , ,
 , , , , , , ,
 , , , , , , ,
 , , , , , , ,
p,p,p,p,p,p,p,p
r,n,b,q,k,b,n,r

R,N,B,Q,K,B,N,R
P,P,P,P,P,P,P,P
 , , , , , , ,
 , , , , , , ,
 , , , ,p, , ,
 , , , , , , ,
p,p,p,p, ,p,p,p
r,n,b,q,k,b,n,r
```

Спецификации
------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-array-objects |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Упорядоченные наборы данных
* `TypedArray`
* `ArrayBuffer`