Przejdź do głównej zawartości

Bug #080

🪲 Znajdź buga

const numbers = {
set current(number) {
this.log.push(number)
},
get latest() {
return this.log.at(-1)
},
log: [],
}

numbers.current = 5
numbers.current = 23

console.log(numbers.log)
console.log(numbers.latest)

const numbersCopy = Object.assign({}, numbers)

numbersCopy.current = 11

console.log(numbersCopy.log)
console.log(numbersCopy.latest)

Chcemy wykonać kopię obiektu, który ma getter'y i setter'y.

Czy kopia w powyższym przykładzie się powiedzie?

Jakie wartości zostaną zalogowane do konsoli?

🧪 Rozwiązanie

const numbers = {
set current(number) {
this.log.push(number)
},
get latest() {
return this.log.at(-1)
},
log: [],
}

numbers.current = 5
numbers.current = 23

console.log(numbers.log) // [5, 23]
console.log(numbers.latest) // 23

const numbersCopy = Object.assign({}, numbers)

numbersCopy.current = 11

console.log(numbersCopy.log) // [5, 23]
console.log(numbersCopy.latest) // 23

Obiekt numbers sam w sobie działa poprawnie.

Umożliwia ustawianie liczby poprzez dodanie jej do tablicy log, a następnie pobranie ostatnio ustawionej liczby poprzez getter latest().

numbers.log zwraca więc [5, 23] ponieważ te dwie liczby zostały wcześniej ustawione poprzez setter current(), tym samym lądując w tablicy log.

numbers.latest zwraca ostatnio ustawioną liczbę, pobierając ją jako ostatni element z tablicy, czyli 23.

Skopiowanie obiektu za pomocą Object.assign() (ale również innymi metodami jak np. rozkład obiektu - spread), nie daje możliwości kopiowania metod w tym getter'ów, czy setter'ów.

numbersCopy.current przestaje działać i staje się niezdefiniowany.

numbersCopy.current = 11 tworzy nową własność, do której na sztywno zostaje przypisana wartość 11.

Operacja ta w żaden sposób nie wpływa już na tablicę log w skopiowanym obiekcie.

numbersCopy.log zwraca tą samą tablicę co numbers.log, ponieważ została ona skopiowana z oryginalnego obiektu.

Niespodzianką może być numbersCopy.latest, ponieważ zwraca 23.

Mimo, że metody obiektu nie są kopiowane, to w przypadku getter'a jest on wykonany w momencie kopiowania i wartość, którą zwraca, zostaje przypisana na stałe do własności w skopiowanym obiekcie.

numbersCopy.latest nie jest już więc metodą zwracającą dynamicznie ostatni element z tablicy log, a jedynie sztywną wartością, do której na stałe przypisana została wartość 23.

🎢 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