Array.copyWithin() — копіювання елементів усередині масиву


Опис

Метод copyWithin надає можливість легко переміщати частини масиву всередині самого масиву без необхідності використання додаткових змінних або циклів. Особливістю методу copyWithin є його ефективність та зручність у використанні. Це корисний інструмент, особливо коли потрібно швидко змінити порядок елементів або дублювати частини масиву. Така можливість стає незамінною у різноманітних задачах обробки даних. Для тих, хто знайомий з мовами програмування C або C++, ця операція може нагадати функцію memmove, яка використовується для копіювання блоків пам'яті.

Як використовувати метод copyWithin?

Уявімо, що у вас є масив чисел, і вам потрібно перемістити частину цього масиву на інше місце всередині того ж масиву. Метод copyWithin дозволяє це зробити, вказавши декілька параметрів: де починати вставку, звідки брати дані та де закінчувати копіювання. Завдяки цьому методу, ви можете швидко та ефективно організовувати свої дані без великих зусиль.

// Маємо початковий масив чисел
let numbers = [1, 2, 3, 4, 5];

// Використовуємо метод copyWithin, щоб взяти числа "2" та "3" 
// і помістити їх на місце чисел "4" та "5"
numbers.copyWithin(3, 1, 3);

console.log(numbers); 
// Результат: [1, 2, 3, 2, 3]

У цьому прикладі ми використовуємо copyWithin, щоб копіювати елементи з позицій 1 до 3 (не включно) та вставляти їх, починаючи з позиції 3.

Важливо зазначити, що undefined конвертується в 0 під час перетворення на ціле число. Отже, якщо не задати параметр start, це буде еквівалентно заданню 0. Це призводить до копіювання всього масиву на потрібну позицію, що є схожим на правий зсув: права частина втрачається, а ліва – дублюється. Щоб уникнути плутанини, краще явно вказувати 0 як значення для start.

автор: Bond

Загальний опис

автор: NagarD

Нотатка

Основна перевага використання методу copyWithin() полягає в тому, що він здійснює маніпуляції з елементами масиву на місці, без створення нового масиву або модифікації розміру масиву. Це дозволяє ефективно виконувати операції копіювання елементів в межах самого масиву.

автор: Bond
Нотатка

Використання методу copyWithin() також дозволяє вказувати від'ємні значення для позицій target, start та end, що вказує на відлік позицій від кінця масиву. Це може бути корисною функціональністю для вибору певних ділянок масиву.

автор: Bond
Нотатка

Метод copyWithin() є мутуючим, а це означає, що він не змінює довжину this, але впливає на його вміст, може додавати нові властивості або видаляти існуючі, якщо це потрібно.

автор: Bond
Нотатка

Метод copyWithin() універсальний. Він очікує, що у this буде властивість length та властивості з цілими числовими ключами. Проте, не дивлячись на те, що рядки також схожі на масиви, цей метод не підходить для їх обробки, адже рядки незмінні.

автор: Bond
Нотатка

Метод copyWithin() зберігає порожні слоти. Так, якщо копійована область є розрідженою, нові індекси порожніх слотів також видаляються та стають порожніми.

автор: Bond

Синтаксис

copyWithin(target, start)
copyWithin(target, start, end)

Параметри

target

В якості параметра target вказується ціле число, яке вказує індекс, до якого копіювати послідовність.

  • Від'ємний індекс враховується з кінця масиву — якщо target < 0, використовується target + array.length.
  • Якщо target < -array.length, використовується 0.
  • Якщо target >= array.length, нічого не копіюється.
  • Якщо target розташовано після start після нормалізації, копіювання відбувається лише до кінця array.length (іншими словами, copyWithin() ніколи не розширює масив).
автор: Bond

start

В якості параметра start вказується ціле число, яке вказує індекс, з якого починається копіювання елементів.

  • Від'ємний індекс враховується з кінця масиву — якщо start < 0, використовується start + array.length.
  • Якщо start < -array.length, використовується 0.
  • Якщо start >= array.length, нічого не копіюється.
автор: Bond

end

В якості параметра end вказується ціле число, на якому має закінчитися копіювання елементів. copyWithin() копіює до, але не включаючи end.

  • Від'ємний індекс враховується з кінця масиву — якщо end < 0, використовується end + array.length.
  • Якщо end < -array.length, використовується 0.
  • Якщо end >= array.length або end не вказаний, використовується array.length, що призводить до копіювання всіх елементів до кінця.
автор: Bond

Повернення

array

Змінений масив.

автор: Bond

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
45 32 9 32 12 —
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
45 45 32 9
Підтримка: серверні переглядачі
Переглядач Node.js Deno
4.0.0 1.0

Приклади

+ запропонувати свій приклад у пісочниці

Після виклику методу copyWithin() елементи масиву заміняються копіями елементів, що знаходяться між початковою та кінцевою позиціями. Результатом є модифікований масив.

console.log([1, 2, 3, 4, 5].copyWithin(0, 3));
// [4, 5, 3, 4, 5]

console.log([1, 2, 3, 4, 5].copyWithin(0, 3, 4));
// [4, 2, 3, 4, 5]

console.log([1, 2, 3, 4, 5].copyWithin(-2, -3, -1));
// [1, 2, 3, 3, 4]
автор: Bond

У даному прикладі, метод copyWithin() викликається на масиві [1, , 3] з аргументами 2, 1, 2, що означає скопіювати елементи з позиції 1 (включно) до позиції 2 (виключно) до позиції 2. Результатом буде [1, empty, empty], де empty позначає порожні слоти.

console.log([1, , 3].copyWithin(2, 1, 2)); // [1, empty, empty]
автор: Bond

Перший виклик copyWithin() копіює елемент з позиції 3 в початкову позицію 0. Другий виклик копіює всі елементи з позиції 3 до кінця масиву в позицію 1.

HTML

<header>
	<h2 class="title">Приклад використання методу copyWithin()</h2>
	<p class="description">Цей приклад демонструє використання методу copyWithin() для копіювання елементів масиву до інших позицій.</p>
</header>
<main>
  <pre>
// Оригінальний масив
const array1 = ['a', 'b', 'c', 'd', 'e'];
  </pre>
	<div id="output1"></div>
	<div id="output2"></div>
</main>

CSS

body {
  font-size: 16px;
  line-height: 1.5;
  font-family: monospace;
}

pre {
  color: #ff0000;
}

header {
  background-color: #f1f1f1;
  margin-bottom: 25px;
  padding: 15px;
  box-shadow: 0px 0px 3px 0px rgba(118, 118, 118, 1);
}

header h2.title {
  padding-bottom: 15px;
  border-bottom: 1px solid #999;
}

header p.description {
  font-style: italic;
  color: #222;
}

JS

const array1 = ['a', 'b', 'c', 'd', 'e'];

document.getElementById("output1").innerText = "Результат 1: " + array1.copyWithin(0, 3, 4);
// Очікуваний результат: Масив ["d", "b", "c", "d", "e"]

document.getElementById("output2").innerText = "Результат 2: " + array1.copyWithin(1, 3);
// Очікуваний результат: Масив ["d", "d", "e", "d", "e"]
//# sourceURL=pen.js
автор: Bond

Прогін перебирає всі межі методу: копіювання проти переміщення, повернений масив, від'ємні індекси, перекриття, об'єкти за посиланням, порожні клітинки й два випадки з TypeError.

// copyWithin(куди, звідки, доки) — КОПІЮЄ шматок усередині того самого масиву
const a = [1, 2, 3, 4, 5];
const povernuv = a.copyWithin(0, 3);
console.log('результат:', a.join(','), '| довжина:', a.length);
console.log('⚠️ повертає ТОЙ САМИЙ масив, а не копію:', povernuv === a);

// ⚠️ це копіювання, а НЕ переміщення: джерело лишається на місці
console.log('[1,2,3,4,5].copyWithin(0, 3, 5) ->', [1, 2, 3, 4, 5].copyWithin(0, 3, 5).join(','),
    '— четвірка й п’ятірка є і на початку, і в кінці');

// третій аргумент не включається — як у slice
console.log('copyWithin(0, 3, 4) ->', [1, 2, 3, 4, 5].copyWithin(0, 3, 4).join(','));
console.log('без другого аргументу ->', [1, 2, 3, 4, 5].copyWithin(0).join(','), '— копіює сам у себе, нічого не змінює');

// від’ємні індекси рахуються з кінця
console.log('copyWithin(-2, 0) ->', [1, 2, 3, 4, 5].copyWithin(-2, 0).join(','));

// ⚠️ довжина НЕ змінюється: усе, що не вміщається, просто відкидається
const korotkyj = [1, 2, 3];
korotkyj.copyWithin(0, 0, 10);
console.log('надлишок відкинуто:', korotkyj.join(','), '| довжина:', korotkyj.length);

// перекриття шматків опрацьовано правильно — як через проміжну копію
console.log('copyWithin(1, 0) ->', [1, 2, 3, 4, 5].copyWithin(1, 0).join(','), '— зсув праворуч без затирання');

// ⚠️ для об’єктів копіюються ПОСИЛАННЯ, а не самі об’єкти
const obj = { n: 1 };
const objects = [obj, { n: 2 }, { n: 3 }];
objects.copyWithin(1, 0, 1);
objects[0].n = 42;
console.log('той самий об’єкт у двох клітинках:', objects[1] === objects[0], '| n:', objects[1].n);

// ⚠️ порожні клітинки переносяться як порожні: клітинка-приймач ЗНИКАЄ
const rozridzhenyj = [1, , 3];
rozridzhenyj.copyWithin(0, 1);
console.log('розріджений [1, , 3] ->', JSON.stringify(rozridzhenyj), '| клітинка 0 існує:', 0 in rozridzhenyj);

// працює і на псевдомасивах через call, і на типізованих масивах
const psevdo = { 0: 'а', 1: 'б', 2: 'в', length: 3 };
Array.prototype.copyWithin.call(psevdo, 0, 1);
console.log('псевдомасив:', JSON.stringify(psevdo));
console.log('типізований:', [...new Uint8Array([1, 2, 3, 4]).copyWithin(0, 2)].join(','));

// ⚠️ рядок так не змінити, заморожений масив теж
try {
    Array.prototype.copyWithin.call('абвг', 0, 2);
} catch (e) {
    console.log('на рядку:', e.name, '— рядки незмінні');
}
try {
    Object.freeze([1, 2, 3]).copyWithin(0, 1);
} catch (e) {
    console.log('на замороженому масиві:', e.name);
}
автор: NagarD

В прикладі використовується об'єкт arrayLike, який не є масивом, але має властивість length та індекс 3. Застосування методу copyWithin() до arrayLike за допомогою Array.prototype.copyWithin.call(arrayLike, 0, 3) копіює значення з індексу 3 в початковий індекс 0, і повертає модифікований об'єкт. Після цього, виклик Array.prototype.copyWithin.call(arrayLike, 3, 1) копіює значення з індексу 1 в індекс 3, але властивість '3' видаляється, оскільки початковий індекс є порожнім слотом.

const arrayLike = {
  length: 5,
  3: 1,
};
console.log(Array.prototype.copyWithin.call(arrayLike, 0, 3));
// { '0': 1, '3': 1, length: 5 }
console.log(Array.prototype.copyWithin.call(arrayLike, 3, 1));
// { '0': 1, length: 5 }
// Властивість '3' видаляється, оскільки скопійоване джерело є порожнім слотом
автор: Bond

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Як форматувати текст?
Пишемо Виходить
**важливо**
*акцент*
~~застаріле~~
Виділення в тексті. Те саме роблять кнопки панелі, що спливає над виділеним.
## Як працює каскад
### Порядок оголошень
Заголовки всередині тексту. Найбільший не потрібен — він у сторінки вже є.
[[css/property/color]] Посилання на сторінку довідника. Наберіть [[ — поле веде сходинками (розділ → тип → сторінка), а хибний ключ підкреслить хвилею.
[[!sandbox/S0oh1hBm]] Живий приклад окремим рядком — саме вікно результату. Той самий ключ зі знаком !: наберіть [[! і дійдіть сходинками до потрібної сторінки, список покаже її приклади.
[MDN](https://developer.mozilla.org) Посилання на чужий сайт.
![Схема каскаду](https://site.com/схема.png) Картинка. Опис обов'язковий: його читають пошуковик і незрячі.
Задайте `display: grid` контейнеру Код усередині речення.
```css
.card { display: grid }
```
Код блоком. Мова після трьох лапок вмикає підсвітку.
- Походження
1. Походження
Перелік: маркований і нумерований.
- [ ] дописати приклади
- [x] перевірити в Firefox
Перелік завдань із галочками. Пробіл у порожніх дужках обов'язковий.
> Порядок важить лише за рівної ваги. Цитата на всю ширину абзацу.
Специфічність
: вага селектора; більша перемагає
Список означень: термін, а під ним пояснення з відступом. Пробіл після двокрапки обов'язковий.
Каскад має три критерії[^1]
[^1]: Походження, специфічність, порядок.
Виноска: номер у тексті, примітка внизу сторінки. Без згадки [^1] у тексті примітка не з'явиться.
Відповідь: ||сорок два|| Ховає те, що між рисками: читач бачить на цьому місці розмиту пляму, а решта речення лишається звичайною. Клац — і текст відкрито.
|| Показати рішення
Задайте контейнеру `display: grid`.
||
Ховає цілі абзаци. На сторінці видно лише підпис із першого рядка («Показати рішення»), решта розгортається клацанням по ньому. Закривні риски — окремим рядком.
Порожній рядок Новий абзац. Щоб перенести рядок усередині абзацу, поставте \ в його кінці.

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Правка
Зворотний зв'язок
Вхід