Learn JavaScript

with() - метод для замены элемента массива без изменения исходного массива в JavaScript

with() возвращает новый массив, в котором один элемент заменён на другое значение.

Главная идея метода очень простая: он позволяет изменить элемент по индексу, не меняя исходный массив.

Синтаксис

array.with(index, value)

index - индекс элемента, который нужно заменить.

value - новое значение.

Что делает with()

Метод создаёт новую версию массива и подставляет новое значение в указанную позицию.

const numbers = [10, 20, 30];
const result = numbers.with(1, 99);

console.log(result);  // [10, 99, 30]
console.log(numbers); // [10, 20, 30]

Это главное, что важно запомнить: with() не меняет исходный массив.

Замена элемента по индексу

Самый обычный пример - заменить один элемент в середине массива.

const fruits = ["apple", "banana", "orange"];
const result = fruits.with(1, "kiwi");

console.log(result); // ["apple", "kiwi", "orange"]

Исходный массив не меняется

После вызова with() старый массив остаётся прежним.

const items = ["a", "b", "c"];
const newItems = items.with(0, "x");

console.log(items);    // ["a", "b", "c"]
console.log(newItems); // ["x", "b", "c"]

Это делает with() удобным в коде, где важно не менять исходные данные.

Отрицательные индексы

with() поддерживает отрицательные индексы.

В этом случае отсчёт идёт с конца массива.

const numbers = [1, 2, 3, 4];

console.log(numbers.with(-1, 99)); // [1, 2, 3, 99]
console.log(numbers.with(-2, 88)); // [1, 2, 88, 4]

Это удобно, когда нужно заменить один из последних элементов.

Что возвращает with()

with() возвращает новый массив.

const numbers = [1, 2, 3];
const result = numbers.with(2, 100);

console.log(result); // [1, 2, 100]

Это не тот же самый массив, а новая копия.

const numbers = [1, 2, 3];
const result = numbers.with(1, 9);

console.log(result === numbers); // false

Если индекс вне диапазона

Если передать индекс, которого в массиве нет, метод выбросит ошибку.

const numbers = [1, 2, 3];

// numbers.with(5, 99); // RangeError
// numbers.with(-5, 99); // RangeError

Это важное отличие от обычного присваивания через квадратные скобки.

with() и обычное присваивание

Обычная запись через индекс меняет исходный массив:

const numbers = [1, 2, 3];

numbers[1] = 99;

console.log(numbers); // [1, 99, 3]

with() делает похожую замену, но возвращает новый массив:

const numbers = [1, 2, 3];
const result = numbers.with(1, 99);

console.log(numbers); // [1, 2, 3]
console.log(result);  // [1, 99, 3]

with() и splice()

Оба варианта могут заменить элемент, но работают по-разному.

const numbers = [1, 2, 3];
const result = numbers.with(1, 99);

console.log(numbers); // [1, 2, 3]
console.log(result);  // [1, 99, 3]

with() не меняет исходный массив.

splice() меняет исходный массив прямо на месте.

Поверхностная копия

with() создаёт поверхностную копию массива.

Это значит, что вложенные объекты внутри массива не копируются глубоко.

const users = [{ name: "Anna" }, { name: "Ivan" }];
const copy = users.with(1, users[1]);

copy[0].name = "Oleg";

console.log(users[0].name); // "Oleg"

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

Когда это полезно

with() удобно использовать, когда:

  • нужно заменить элемент массива без изменения исходного
  • важно сохранить предыдущее значение массива
  • код написан в неизменяемом стиле

Частые ошибки

Думать, что with() меняет массив

const numbers = [1, 2, 3];

numbers.with(1, 9);

console.log(numbers); // [1, 2, 3]

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

Забывать, что индекс должен существовать

const numbers = [1, 2, 3];

// numbers.with(10, 5); // RangeError

Метод не расширяет массив автоматически.

Путать with() и splice()

const numbers = [1, 2, 3];

numbers.with(1, 99);

Этот код не меняет массив. Если ожидается изменение на месте, with() для этого не подходит.

Быстрая памятка

  • with() заменяет элемент по индексу и возвращает новый массив
  • исходный массив не меняется
  • метод поддерживает отрицательные индексы
  • если индекс вне диапазона, будет RangeError
  • with() создаёт поверхностную, а не глубокую копию

Коротко

with() - это удобный способ заменить элемент массива без мутации исходных данных. Главное, что стоит запомнить: метод возвращает новый массив и особенно полезен там, где важно не менять старый.