Przejdź do głównej zawartości

Bug #092

🪲 Znajdź buga

const person = {
name: "John",
height: 178,
birthdate: new Date("1999-12-31"),
children: [
{
name: "John Junior",
height: 132,
birthdate: new Date("2022-02-22"),
},
],
}

const copy1 = JSON.parse(JSON.stringify(person))
const copy2 = { ...person }
const copy3 = structuredClone(person)

person.children[0].name = "Susan"

console.log(person.birthdate.getTime())
console.log(person.children[0])

console.log(copy1.birthdate.getTime())
console.log(copy1.children[0])

console.log(copy2.birthdate.getTime())
console.log(copy2.children[0])

console.log(copy3.birthdate.getTime())
console.log(copy3.children[0])

Chcemy skopiować obiekt w sposób głęboki (deep clone).

W jaki sposób zadziałają różne metody kopiowania?

Jakie wartości zostaną zalogowane do konsoli?

🧪 Rozwiązanie

const person = {
name: "John",
height: 178,
birthdate: new Date("1999-12-31"),
children: [
{
name: "John Junior",
height: 132,
birthdate: new Date("2022-02-22"),
},
],
}

const copy1 = JSON.parse(JSON.stringify(person))
const copy2 = { ...person }
const copy3 = structuredClone(person)

person.children[0].name = "Susan"

console.log(person.birthdate.getTime())
console.log(person.children[0])

// console.log(copy1.birthdate.getTime())
console.log(copy1.children[0])

console.log(copy2.birthdate.getTime())
console.log(copy2.children[0])

console.log(copy3.birthdate.getTime())
console.log(copy3.children[0])

Wywołanie metody getTime() na copy1.birthdate zwróci błąd informujący, że getTime nie jest funkcją.

Mimo, że serializacja i parsowanie formatu JSON działa jako głęboka kopia obiektu, to przez konwersję do formatu JSON tracimy niektóre pierwotne własności obiektu jak funkcje.

Skopiowana data zostaje skonwertowana do ciągu znaków. Nie możemy więc wywoływać na niej metody getTime().

Głęboka kopia copy2 poprzez operator rozkładu { ...person } nie kopiuje zagnieżdżonych obiektów (w tym tablic), a jedynie przekazuje referencję do nich.

Modyfikując imię dziecka w oryginalnym obiekcie po wcześniejszym wykonaniu kopi poprzez rozkład, wpływamy na zmianę tego imienia również w skopiowanym obiekcie.

Ostatni, trzeci sposób jest najskuteczniejszy dla tworzenia głębokich kopi.

Dla copy3 globalna funkcja structuredClone() wykonuje głęboką kopię, zachowując funkcjonalności oraz kopiując zagnieżdżone obiekty.

🎢 Plac zabaw

Otwórz edytor w nowym oknie

📑 Linki

❤️ Podobają Ci się bugi JS?

Podziel się linkiem ze znajomymi:
https://codisity.pl/100-bugow-js