ΠΡŽΠ°Π½ΡΡ‹ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² JavaScript

Π’ языкС JavaScript ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΉ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒΡŽ являСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ β€” структура Π΄Π°Π½Π½Ρ‹Ρ…, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ хранятся значСния, ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ассоциировано с ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ β€” строкой ΠΈΠ»ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΈΠΏΠ° Symbol. ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² JS ΡΠ²Π»ΡΡŽΡ‚ΡΡ основой ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ½ΠΎΠ³ΠΎ наслСдования, которая позволяСт Π²Ρ‹ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡŽ сущностСй Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅. Они Π»Π΅ΠΆΠ°Ρ‚ Π² основС ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Π½Π΅ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ массивы, мноТСства, ΠΌΠ°ΠΏΡ‹ ΠΈ Π΄Π°ΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² JS Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ ΡΠ²Π»ΡΡ‚ΡŒΡΡ значСниями. Π’ ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½Ρ‹Π΅ значСния, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ числа ΠΈ строки, ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒΡΡ срСдой исполнСния Π½Π° этапС ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠΈ ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΅ΡΡ‚ΡŒ собствСнныС свойства ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹.

ΠšΡ€ΠΎΠΌΠ΅ основы для Ρ€Π°Π±ΠΎΡ‚Ρ‹ самого языка, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² JavaScript β€” это ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ способ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, относящиСся ΠΊ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π½ΠΎΠΉ области ΠΈ ΡΡ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ эти Π΄Π°Π½Π½Ρ‹Π΅ Ρ‡Π΅Ρ€Π΅Π· связи ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π’ Ρ€Π°Π±ΠΎΡ‚Π΅ с этими структурами Π΄Π°Π½Π½Ρ‹Ρ… Π΅ΡΡ‚ΡŒ мноТСство нюансов, ΠΈ сСгодня я Ρ…ΠΎΡ‚Π΅Π» Π±Ρ‹ ΠΎΠ±ΡΡƒΠ΄ΠΈΡ‚ΡŒ Π½ΡŽΠ°Π½ΡΡ‹ Ρ‚Π°ΠΊΠΎΠΉ часто Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‰Π΅ΠΉΡΡ Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΊΠ°ΠΊ созданиС ΠΊΠΎΠΏΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² JavaScript.

ΠŸΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚Π½Ρ‹Π΅ ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²

Π’ JavaScript значСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎ ссылкС Π½Π° ячСйку памяти, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ хранится это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ значСния ΠΈΠ· ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, содСрТащСй ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ лишь ΠΊ созданию Π½ΠΎΠ²ΠΎΠΉ ссылки, Π½ΠΎ Π½Π΅ ΠΊ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ самого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°:

const object = { a: 1, b: 2 };

const clone = object;

console.log(object === clone); // true

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈ внСсСнии ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ с ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ΠΌ ΠΊ любой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ исходный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:

object.a = 2;

clone.b = 3;

console.log(object); // { a: 2, b: 3 }
console.log(clone); // { a: 2, b: 3 }

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½ΡƒΡŽ копию ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ Object.assign():

const object = { a: 1, b: 2 };

const clone = Object.assign({}, object);

console.log(object === clone); // false

Или ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ ...:

const object = { a: 1, b: 2 };

const clone = { ...object };

console.log(object === clone); // false

Π’Π°ΠΊΠΆΠ΅ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Ρ€Π°Π½Π΅Π΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈ Π² Ρ†ΠΈΠΊΠ»Π΅ for...in ΠΏΠ΅Ρ€Π΅Π±Ρ€Π°Ρ‚ΡŒ свойства исходного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… Π² Π½ΠΎΠ²Ρ‹ΠΉ:

const object = { a: 1, b: 2 };

const clone = {};

for (const key in object) {
  clone[key] = object[key];
}

console.log(object === clone); // false

Π­Ρ‚ΠΈ способы ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ подходят для создания β€œΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚Π½Ρ‹Ρ…β€ ΠΊΠΎΠΏΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅Ρ‚ свойств, содСрТащих Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. Если ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ содСрТит Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹Π΅ свойства, ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ скопированы Π½Π΅ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, Π° ΠΏΠΎ ссылкС:

const object = { a: 1, b: { c: 2 } };

const clone = { ...object };

object.b.c = 3;

console.log(clone.b); // { c: 3 }

console.log(object.b.c === clone.b.c); // true

Π­Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ для Π»ΡŽΠ±Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ: самих ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², массивов, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, экзСмпляров классов ΠΈΠ»ΠΈ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ-конструкторов, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°ΡŽΡ‰ΠΈΡ…ΡΡ ΠΏΠΎ ссылкС.

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° Π·Π°Π΄Π°Ρ‡ Ρ…Π²Π°Ρ‚Π°Π΅Ρ‚ плоских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΈ Π² Ρ†Π΅Π»ΠΎΠΌ Ρ…ΠΎΡ€ΠΎΡˆΠ΅ΠΉ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΡΡ‚Ρ€Π΅ΠΌΠΈΡ‚ΡŒΡΡ ΠΊ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½ΠΈΡŽ ΠΈ β€œΡƒΠΏΠ»ΠΎΡ‰Π΅Π½ΠΈΡŽβ€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ повСрхностноС ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. Π­Ρ‚ΠΎ простая ΠΈ быстровыполнимая Π·Π°Π΄Π°Ρ‡Π° для ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ общСпринятый ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€Π΅Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌΠΈ Ρ‚ΠΈΠΏΠ° React.js, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΠΈΡ€Π°ΡŽΡ‚ΡΡ Π½Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ повСрхностного сравнСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² пропсов для опрСдСлСния ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² Π½ΠΈΡ… ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π΅Π½Π΄Π΅Ρ€Π°ΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².

Π“Π»ΡƒΠ±ΠΎΠΊΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²

Но Π½Π΅ всС Π·Π°Π΄Π°Ρ‡ΠΈ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ плоских ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Иногда Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ β€œΠ³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎβ€ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ рСкурсивно ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ всС Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹Π΅ свойства Π½Π΅ ΠΏΠΎ ссылкС, Π° ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Ρ‚Π°ΠΊΠΈΡ… Π·Π°Π΄Π°Ρ‡:

  • ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ΠΊΠΎΠΏΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½Ρ‹ΠΌΠΈ контСкстами: ΠΎΠΊΠ½Π°ΠΌΠΈ, Ρ„Ρ€Π΅ΠΉΠΌΠ°ΠΌΠΈ ΠΈ Π²ΠΎΡ€ΠΊΠ΅Ρ€Π°ΠΌΠΈ;
  • сохранСниС слСпков состояний для ΠΈΡ… сравнСния, пСрСмСщСния ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ ΠΈ хранСния истории ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ;
  • ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… Π² Π±ΡƒΡ„Π΅Ρ€Π΅ ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΡ… сохранСниСм;
  • созданиС ΠΊΠΎΠΏΠΈΠΉ состояний для провСдСния ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… тСстов;
  • ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ состояний ΠΈ изоляция ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ.

НС сущСствуСт простого ΠΈ прямого способа ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ со всСми Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ свойствами, содСрТащими Π»ΡŽΠ±Ρ‹Π΅ значСния. НиТС ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽ Ρ€Π°ΡΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ самыС популярныС способы Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΈΡ… ограничСния ΠΈ Π½ΡŽΠ°Π½ΡΡ‹ использования.

Бпособы Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²

JSON.parse(JSON.stringify(object))

Π­Ρ‚ΠΎΡ‚ способ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΎΡ‡Π΅Π½ΡŒ быстро , Π½ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ ограничСния ΠΏΠΎ Ρ‚ΠΈΠΏΠ°ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ сСриализованы ΠΈ дСсСриализованы, Ρ‚.Π΅. ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½Ρ‹ ΠΊ строкС ΠΈ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ восстановлСны ΠΈΠ· этой строки Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ мСстС. К Ρ€Π°Π·Ρ€Π΅ΡˆΡ‘Π½Π½Ρ‹ΠΌ Ρ‚ΠΈΠΏΠ°ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ относятся Ρ‚ΠΈΠΏΡ‹, доступныС для использования Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ JSON β€” это строки, числа, Π±ΡƒΠ»Π΅Π²Ρ‹Π΅ значСния, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, массивы ΠΈ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ null.

ЗначСния всСх ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ ΠΊ структурС Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° JSON Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ способами. Они ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ (Π² случаС с undefined ΠΈΠ»ΠΈ функциями Π² Π²ΠΈΠ΄Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ), Π·Π°ΠΌΠ΅Π½Π΅Π½Ρ‹ Π½Π° пустой ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ {} (ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Ρ‚Π°ΠΊΠΈΠΌΠΈ встроСнными структурами ΠΈ классами, ΠΊΠ°ΠΊ Set, Map, RegExp, Error ΠΈ ΠΏΡ€.), ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Ρ‹ встроСнным ΠΈΠ»ΠΈ самописным ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ toJSON() Π² случаС Π΅Π³ΠΎ наличия (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ½ описан Π²ΠΎ встроСнном ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ Date), ΠΈΠ»ΠΈ ΠΆΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½Ρ‹ ΠΊ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρƒ JSON ΠΈΠ½Ρ‹ΠΌ способом.

ОписаниС всСх Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… случаСв прСобразования Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΊ JSON-строкС ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° MDN .

БСриализация ΠΈ дСсСриализация ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ встроСнного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° JSON:

const object = {
  set: new Set([1, 3, 3]),
  regex: /abc/,
  date: new Date(123),
  string: "hello",
  array: [false, 1, "2"],
  node: document.body,
  function() {
    return 123;
  },
  withToJSON: {
    a: 1,
    toJSON() {
      return { a: 2 };
    },
  },
  obj: {
    a: 1,
    b: {
      c: 2,
    },
  },
};

const clone = JSON.parse(JSON.stringify(object));

ПослС прСобразования ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² clone:

{
  "set": {},
  "regex": {},
  "date": "1970-01-01T00:00:00.123Z",
  "string": "hello",
  "array": [
    false,
    1,
    "2"
  ],
  "node": {},
  "withToJSON": {
    "a": 2
  },
  "obj": {
    "a": 1,
    "b": {
      "c": 2
    }
  }
}

Π£ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° Π΅ΡΡ‚ΡŒ ограничСния: ΠΎΠ½ Π½Π΅ позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ содСрТат β€œΡ†ΠΈΠΊΠ»ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ ссылки”, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ свойства, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ содСрТат ссылку Π½Π° исходный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. ΠŸΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΠΈ:

const object = { a: 1 };

object.a = object;

console.log(JSON.stringify(object)); // Uncaught TypeError: Converting circular structure to JSON

Ошибка Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π° ΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ сСриализации значСния Ρ‚ΠΈΠΏΠ° BigInt:

const object = { a: 100000n };

console.log(JSON.stringify(object)); // Uncaught TypeError: Do not know how to serialize a BigInt

Нюансами сСриализации ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ replacer, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠΉ Π² JSON.stringify() Π² качСствС Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. Π’ этой ΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ значСния, приводящиС ΠΊ ошибкам сСриализации:

const object = { a: 1, b: 100000n };

object.a = object;

const replacer = (key, value) => {
  value = typeof value === "bigint" ? String(value) : value;

  return key === "a" ? undefined : value;
};

const clone = JSON.parse(JSON.stringify(object, replacer));

console.log(clone); // { b: '100000' }

ΠŸΠΎΡ…ΠΎΠΆΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Π΅ΡΡ‚ΡŒ ΠΈ Ρƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° JSON.parse() β€” ΠΎΠ½ называСтся reviver ΠΈ позволяСт ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΡŽΠ°Π½ΡΡ‹ дСсСриализации (восстановлСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ· строки):

const object = { date: new Date(123) };

const stringifiedObject = JSON.stringify(object);

console.log(stringifiedObject); // '{"date":"1970-01-01T00:00:00.123Z"}'

const reviver = (key, value) => {
  return key === "date" ? new Date(value).getMilliseconds() : value;
};

console.log(JSON.parse(stringifiedObject, reviver)); // { date: 123 }

v8.deserialize(v8.serialize(object))

Бтроковая сСриализация ΠΈ дСсСриализация ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ JSON.stringify() ΠΈ JSON.parse() доступна ΠΈ Π² срСдС Node.js. ΠšΡ€ΠΎΠΌΠ΅ этого Π² Node.js Π΅ΡΡ‚ΡŒ Π΅Ρ‰Ρ‘ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ…ΠΎΠΆΠΈΠΉ способ Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π±ΠΈΠ½Π°Ρ€Π½ΡƒΡŽ ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΈ Π΄Π΅ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π‘ΠΈΠ½Π°Ρ€Π½ΠΎΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ позволяСт Π²ΠΎΡΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ большС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈ дСсСриализации:

const v8 = require("v8");

const object = {
  set: new Set([1, 3, 3]),
  regex: /abc/,
  date: new Date(123),
  string: "hello",
  array: [false, 1, "2"],
  obj: {
    a: 1,
    b: {
      c: 2,
    },
  },
};

const clone = v8.deserialize(v8.serialize(object));

ΠœΠ΅Ρ‚ΠΎΠ΄ v8.serialize() отличаСтся ΠΎΡ‚ JSON.stringify() ΠΈ Π΄Π°Ρ‘Ρ‚ ΠΈΠ½ΠΎΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΡ€ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²:

{
  set: Set(2) { 1, 3 },
  regex: /abc/,
  date: 1970-01-01T00:00:00.123Z,
  string: 'hello',
  array: [ false, 1, '2' ],
  obj: { a: 1, b: { c: 2 } }
}

ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, содСрТащий Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² качСствС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ свойств, ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ ΠΊ ошибкС:

const object = {
  function() {
    return 123;
  },
};

v8.serialize(object); // Uncaught Error: function() { return 123; } could not be cloned

Π‘ΠΈΠ½Π°Ρ€Π½ΠΎΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ цикличСскиС ссылки:

const object = { a: 1 };

object.a = object;

console.log(v8.serialize(object)); // <ref *1> { a: [Circular *1] }
console.log(v8.serialize(object.a)); // <ref *1> { a: [Circular *1] }
console.log(v8.serialize(object.a.a.a.a)); // <ref *1> { a: [Circular *1] }

lodash.cloneDeep(object)

Ѐункция cloneDeep ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ lodash β€” популярноС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ для Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². cloneDeep рСкурсивно проходится ΠΏΠΎ всСм свойствам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ ΠΊΠ»ΠΎΠ½ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈΡ… ΠΏΠΎ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ.

cloneDeep ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ цикличСскиС ссылки, ΠΈ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ с ошибкой ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с функциями, копируя ΠΈΡ… ΠΏΠΎ ссылкС, Π° Π½Π΅ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. Π’Π°ΠΊΠΎΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄ Object.create(), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСт Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π·Π°Π΄Π°Ρ‘Ρ‚ Π΅ΠΌΡƒ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π² Π²ΠΈΠ΄Π΅ исходной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ пСрСприсваиваСт этот ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ свойство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°-ΠΊΠΎΠΏΠΈΠΈ:

import _ from "lodash";

const func = () => 123;

const object = { func };

const clone = _.cloneDeep(object);

// Π­ΠΌΡƒΠ»ΠΈΡ€ΡƒΠ΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ cloneDeep: создаём Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠΎΠΌ
// Π² Π²ΠΈΠ΄Π΅ исходной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ пСрСприсваиваСм этот ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Π² Π½ΠΎΠ²ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ
const funcClone = Object.getPrototypeOf(Object.create(func));

// Π‘Ρ€Π°Π²Π½ΠΈΠ²Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΏΠΎ ссылкС
console.log(funcClone === object.func); // true
console.log(funcClone === clone.func); // true

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, cloneDeep Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ с ошибкой ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с функциями ΠΈ позволяСт Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡ… ΠΏΠΎ ссылкС ΠΈΠ· ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°-ΠΊΠΎΠΏΠΈΠΈ с ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ лСксичСским ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ΠΌ.

structuredClone(object)

Π“Π»ΡƒΠ±ΠΎΠΊΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ самой срСдой исполнСния ΠΊΠΎΠ΄Π° JavaScript для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… Π·Π°Π΄Π°Ρ‡. Π—Π° ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² со слоТной структурой Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½Ρ‹Ρ… API ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ structured clone algorithm . Π­Ρ‚ΠΎΡ‚ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для создания ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΅Π³ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ Π²ΠΎΡ€ΠΊΠ΅Ρ€Π°ΠΌΠΈ Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄ postMessage(), для хранСния Π΄Π°Π½Π½Ρ‹Ρ… Π² IndexedDB, для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сСтСвых запросов ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с кэшСм Π² Service Workers API ΠΈ Ρ‚.Π΄.

Π’ 2021 Π³ΠΎΠ΄Ρƒ Π² Π½ΠΎΠ²Ρ‹Ρ… вСрсиях Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ² стал доступСн встроСнный Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ structuredClone(), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ копию ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° с Π³Π»ΡƒΠ±ΠΎΠΊΠΈΠΌ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ всСх ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ влоТСнности ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ для этого всё Ρ‚ΠΎΡ‚ ΠΆΠ΅ structured clone algorithm. structuredClone() Π½Π΅ являСтся Ρ‡Π°ΡΡ‚ΡŒΡŽ стандарта ECMAScript, Π½ΠΎ доступСн Π² соврСмСнных вСрсиях Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ² ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… хост-систСмах JavaScript.

Π’Π°Π±Π»ΠΈΡ†Ρƒ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π½ΠΎΠΉ совмСстимости ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° caniuse.com .

structuredClone() Ρ‚Π°ΠΊΠΆΠ΅ доступСн Π² срСдах Node.js >= 17.0.0 ΠΈ Deno >= 1.13.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования structuredClone():

const object = {
  set: new Set([1, 3, 3]),
  regex: /abc/,
  date: new Date(123),
  string: "hello",
  array: [false, 1, "2"],
  obj: {
    a: 1,
    b: {
      c: 2,
    },
  },
};

const clone = structuredClone(object);

Новый ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ clone Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

{
  set: Set(2) { 1, 3 },
  regex: /abc/,
  date: 1970-01-01T00:00:00.123Z,
  string: "hello",
  array: [false, 1, "2"],
  obj: {
    a: 1,
    b: {
      c: 2
    }
  },
}

Π­Ρ‚ΠΎΡ‚ способ Π½Π΅ позволяСт ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² качСствС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈ DOM-ΡƒΠ·Π»Ρ‹, ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ значСния Π±ΡƒΠ΄Π΅Ρ‚ Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ DataCloneError:

const func = () => 123;

const object = { func };

const clone = structuredClone(object); // Uncaught DOMException: Failed to execute 'structuredClone' on 'Window': () => 123 could not be cloned
const node = document.body;

const object = { node };

const clone = structuredClone(object); // Uncaught DOMException: Failed to execute 'structuredClone' on 'Window': HTMLBodyElement object could not be cloned

structuredClone() Π½Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ дСксрипторы свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, сСттСры ΠΈ Π³Π΅Ρ‚Ρ‚Π΅Ρ€Ρ‹, ΠΈ Π² случаС с Π³Π΅Ρ‚Ρ‚Π΅Ρ€ΠΎΠΌ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° Π½Π΅ саму Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Π³Π΅Ρ‚Ρ‚Π΅Ρ€:

const object = {
  get func() {
    return 123;
  },
};

const clone = structuredClone(object);

console.log(clone); // { func: 123 }

Π’Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ экзСмпляр класса ΠΈΠ»ΠΈ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-конструктора, Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ° ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠΎΠ² Π±ΡƒΠ΄Π΅Ρ‚ потСряна, ΠΈ скопированный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° класс, ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΎΠ½ наслСдовался:

class A {
  constructor() {
    this.a = 1;
  }
}

const object = new A();

const clone = structuredClone(object);

console.log(object instanceof A); // true
console.log(clone instanceof A); // false

ΠŸΠΎΠ»Π½Ρ‹ΠΉ список Ρ‚ΠΈΠΏΠΎΠ² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, подходящих для Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ копирования Π² Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ structuredClone(), ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° MDN .

Π’Π°ΠΆΠ½ΠΎ ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ structuredClone() ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ с цикличСскими ссылками Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ JSON.stringify().

Какой способ копирования Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ, ΠΏΠ»ΡŽΡΡ‹ ΠΈ минусы

Для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° Π·Π°Π΄Π°Ρ‡ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΏΠΎΠ΄ΠΎΠΉΠ΄ΡƒΡ‚ способы β€œΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚Π½ΠΎΠ³ΠΎβ€ копирования, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Object.assign() ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ .... Π­Ρ‚ΠΈ способы ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Ρƒ ΠΈ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ синтаксисом, позволяя ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹Ρ… β€œΠΏΠ»ΠΎΡΠΊΠΈΡ…β€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π½ΠΎ ΠΈ ΡΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Π½ΠΎΠ²Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΠ· ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ…:

const object1 = { a: 1 };

const object2 = { b: 2 };

const result = { ...object1, ...object2 };

console.log(result); // { a: 1, b: 2 }

ИспользованиС Ρ†ΠΈΠΊΠ»Π° for...in ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для создания β€œΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚Π½ΠΎΠΉβ€ ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΊΠΎΠ³Π΄Π° Π²Π°ΠΆΠ΅Π½ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ Π½Π°Π΄ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ ΠΈ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ копирования Ρ‚Π΅Ρ… ΠΈΠ»ΠΈ ΠΈΠ½Ρ‹Ρ… свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

Для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡ β€œΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚Π½Ρ‹Ρ…β€ ΠΊΠΎΠΏΠΈΠΉ нСдостаточно, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π΅ всСгда Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ плоскими ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ. Для создания β€œΠ³Π»ΡƒΠ±ΠΎΠΊΠΈΡ…β€ ΠΊΠΎΠΏΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² сущСствуСт нСсколько способов, ΠΈ Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ… Π΅ΡΡ‚ΡŒ свои ΠΏΠ»ΡŽΡΡ‹ ΠΈ минусы.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠΏΠΈΠΈ посрСдством строковой сСриализации ΠΈ дСсСриализации Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ JSON.stringify() ΠΈ JSON.parse() β€” это ΠΎΡ‡Π΅Π½ΡŒ быстрая ΠΈ оптимизированная Π΄Π²ΠΈΠΆΠΊΠ°ΠΌΠΈ Π·Π°Π΄Π°Ρ‡Π°, ΠΎΠ΄Π½Π°ΠΊΠΎ Ρƒ строкового прСобразования самый большой список ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ ΠΏΠΎ доступным Ρ‚ΠΈΠΏΠ°ΠΌ Π΄Π°Π½Π½Ρ‹Ρ…. Π­Ρ‚ΠΎΡ‚ способ ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅, совмСстимым с JSON, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ссли ΠΎΠ½ΠΈ Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ с сСрвСра посрСдством HTTP-запроса.

ΠšΡƒΠ΄Π° больший Π½Π°Π±ΠΎΡ€ доступных для Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ прСобразования Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π±ΠΈΠ½Π°Ρ€Π½ΠΎΠΉ сСриализации ΠΈ дСсСриализации serialize ΠΈ deserialize ΠΈΠ· модуля v8, Π½ΠΎ ΠΎΠ½ΠΈ доступны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ· срСды Node.js.

ΠΠ°ΠΈΠ±ΠΎΠ»ΡŒΡˆΡƒΡŽ свободу Π² Π²Ρ‹Π±ΠΎΡ€Π΅ Ρ‚ΠΈΠΏΠΎΠ² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, доступных для создания ΠΊΠΎΠΏΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², прСдоставляСт функция cloneDeep ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ lodash. Π­Ρ‚ΠΎ ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ, ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ оттСстированный ΠΈ ΠΎΡ‡Π΅Π½ΡŒ популярный ΠΏΠ°ΠΊΠ΅Ρ‚ с Π½Π°Π±ΠΎΡ€ΠΎΠΌ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΡƒΡ‚ΠΈΠ»ΠΈΡ‚, ΠΈ ΠΎΠ½ ΡƒΠΆΠ΅ установлСн Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…. Однако lodash β€” это внСшняя Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ, которая добавляСт лишниС 70Кб Π² ΠΎΠ±Ρ‰ΠΈΠΉ Π±Π°Π½Π΄Π», Π² случаС Ссли Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π±Ρ‹Π»Π° ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π° Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ, ΠΈ ΠΎΠΊΠΎΠ»ΠΎ 17Кб β€” Ссли сработал ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ tree shaking ΠΏΡ€ΠΈ ΠΈΠΌΠΏΠΎΡ€Ρ‚Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ cloneDeep. Если для вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½ΠΎ ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ мСньшим количСством Π²Π½Π΅ΡˆΠ½ΠΈΡ… зависимостСй, Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для β€œΠ³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎβ€ копирования, которая ΡƒΡ‡ΠΈΡ‚Π²Π°Π΅Ρ‚ цикличСскиС ссылки:

const cloneDeep = (obj, visited = new WeakMap()) => {
  // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, Π±Ρ‹Π» Π»ΠΈ ΡƒΠΆΠ΅ скопирован этот ΠΎΠ±ΡŠΠ΅ΠΊΡ‚
  if (visited.has(obj)) {
    return visited.get(obj);
  }

  if (typeof obj !== "object" || obj === null) {
    return obj; // Если ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Π½Π΅ являСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π΅Π³ΠΎ ΠΆΠ΅
  }

  // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ»ΠΈ массив Π² зависимости ΠΎΡ‚ Ρ‚ΠΈΠΏΠ° obj
  const newObj = Array.isArray(obj) ? [] : {};

  // РСгистрируСм Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠ°ΠΊ посСщённый
  visited.set(obj, newObj);

  // РСкурсивно ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ свойства ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ»ΠΈ элСмСнты массива
  for (let key in obj) {
    // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ, являСтся Π»ΠΈ свойство собствСнным (Π½Π΅ унаслСдованным)
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      // РСкурсивно ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт
      newObj[key] = cloneDeep(obj[key], visited);
    }
  }

  return newObj;
};

ΠŸΡ€ΠΈ нСобходимости Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ†ΠΈΠΊΠ»Π° for...in ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ нСстандартных Ρ‚ΠΈΠΏΠΎΠ² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ.

Для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΠΎΠΉΡ‚ΠΈΡΡŒ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΠΎΠ²Ρ‹ΠΌ встроСнным Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ срСды Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ structuredClone(). Он Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎΠΌ Ρ‚ΠΈΠΏΠΎΠ² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, ΠΈ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ DOM-ΡƒΠ·Π»Ρ‹ Π² качСствС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ свойств ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. ΠœΠ΅Ρ‚ΠΎΠ΄ structuredClone() Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π° основС structured clone algorithm, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ с transferable objects .

Transferable objects β€” это ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ бСзопасно доступны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ JavaScript ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, ΠΈ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°ΡŽΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ для рСдактирования Π² ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ послС ΠΈΡ… копирования, Ссли ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ Π²Ρ‹Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΈΠ· MDN ΠΎ сцСнарии использования transferable objects:

Transferable objects ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ пСрСнСсСны, Π° Π½Π΅ ΠΏΡ€ΠΎΠ΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² ΠΊΠ»ΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ свойства transfer ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° options. ΠŸΡ€ΠΈ пСрСносС исходный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ становится Π½Π΅ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π½Ρ‹ΠΌ для использования. Π‘Ρ†Π΅Π½Π°Ρ€ΠΈΠΉ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ β€” асинхронная ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… Π² Π±ΡƒΡ„Π΅Ρ€Π΅ ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΡ… сохранСниСм. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ измСнСния Π±ΡƒΡ„Π΅Ρ€Π° Π΄ΠΎ сохранСния Π΄Π°Π½Π½Ρ‹Ρ…, ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠ»ΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ эти Π΄Π°Π½Π½Ρ‹Π΅. Если Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΡ‚Π΅ Π΄Π°Π½Π½Ρ‹Π΅, Π»ΡŽΠ±Ρ‹Π΅ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ исходный Π±ΡƒΡ„Π΅Ρ€ Π±ΡƒΠ΄ΡƒΡ‚ Π½Π΅ΡƒΠ΄Π°Ρ‡Π½Ρ‹ΠΌΠΈ, Ρ‡Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ Π΅Π³ΠΎ случайноС использованиС Π½Π΅ ΠΏΠΎ Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ:

const uInt8Array = Uint8Array.from({ length: 1024 * 1024 * 16 }, (v, i) => i);

console.log(uInt8Array.byteLength); // 16777216

const transferred = structuredClone(uInt8Array, {
  transfer: [uInt8Array.buffer],
});

console.log(uInt8Array.byteLength); // 0

Π’ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ исслСдовали, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² языкС JavaScript. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ вспомнили ΠΎ ссылочной ΠΏΡ€ΠΈΡ€ΠΎΠ΄Π΅ хранСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ рассмотрСли способы создания β€œΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚Π½Ρ‹Ρ…β€ ΠΊΠΎΠΏΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π”Π°Π»Π΅Π΅ ΠΌΡ‹ познакомились с рядом Π·Π°Π΄Π°Ρ‡, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ нСдостаточно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ β€œΠΏΠ»ΠΎΡΠΊΠΈΠ΅β€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΈ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΈΠ·ΡƒΡ‡ΠΈΠ»ΠΈ Π½ΡŽΠ°Π½ΡΡ‹ β€œΠ³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎβ€ копирования ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² JavaScript, ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½Ρ‹Π΅ свойства. НаконСц, ΠΌΡ‹ сравнили эти способы, ΡƒΠ²ΠΈΠ΄Π΅Π»ΠΈ ΠΈΡ… ΠΏΠ»ΡŽΡΡ‹ ΠΈ минусы ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ случаи, ΠΊΠΎΠ³Π΄Π° Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΡ‚ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄.


ΠŸΡ€ΠΈΠ³Π»Π°ΡˆΠ°ΡŽ вас ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ Π½Π° ΠΌΠΎΠΉ Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»: https://t.me/alexgriss , Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ я ΠΏΠΈΡˆΡƒ ΠΎ Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅, ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΡŽ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹, дСлюсь своим ΠΏΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΌΠ½Π΅Π½ΠΈΠ΅ΠΌ ΠΈ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽ Ρ‚Π΅ΠΌΡ‹, Π²Π°ΠΆΠ½Ρ‹Π΅ для ΠΊΠ°Ρ€ΡŒΠ΅Ρ€Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°.