Przejdź do głównej zawartości

Bug #097

🪲 Znajdź buga

const sym1 = Symbol()
const sym2 = Symbol()

const obj1 = {}
const obj2 = {}

console.log(sym1 === sym2)
console.log(sym1 === sym1)

console.log(obj1 === obj2)
console.log(obj1 === obj1)

const test = {}

test[sym1] = "Foo"
test[sym2] = "Bar"

test[obj1] = "Baz"
test[obj2] = "Qux"

console.log(test[sym1])
console.log(test[sym2])

console.log(test[obj1])
console.log(test[obj2])

console.log(test)

Jaki wartości zostaną zalogowane do konsoli?

Czy są jakieś różnice pomiędzy użyciem obiektu, a symbolu jako nazwy własności innego obiektu?

🧪 Rozwiązanie

const sym1 = Symbol()
const sym2 = Symbol()

const obj1 = {}
const obj2 = {}

console.log(sym1 === sym2) // false
console.log(sym1 === sym1) // true

console.log(obj1 === obj2) // false
console.log(obj1 === obj1) // true

const test = {}

test[sym1] = "Foo"
test[sym2] = "Bar"

test[obj1] = "Baz"
test[obj2] = "Qux"

console.log(test[sym1]) // "Foo"
console.log(test[sym2]) // "Bar"

console.log(test[obj1]) // "Qux"
console.log(test[obj2]) // "Qux"

console.log(test) // {[object Object]: "Qux"}

Porównywanie ze sobą symboli oraz obiektów, które zostały zdefiniowane niezależnie, da nam ten same efekt - fałsz.

Jedynie porównywanie tych samych stałych, które przechowują dany obiekt lub symbol zwróci prawdę.

Wówczas porównywane będą rzeczywiście te same obiekty/symbole, przechowywane w pamięci pod adresem na który wskazuje dana stała.

Na tym etapie podobieństwa obiektów i symboli z grubsza się kończą.

Symbole z natury służą do utworzenia unikalnej wartości.

Nie są też konwertowane do ciągu znaków w sytuacjach wymuszających tego typu operację.

test[sym1] i test[sym2] zalogują do konsoli "Foo" i "Bar".

Co ważne, test[Symbol()] zwróci undefined, bo jak już wcześniej ustaliliśmy, każdy nowo utworzony symbol jest unikalny.

Jednocześnie własności zdefiniowane za pomocą symboli nie będą widoczne po zalogowania do konsoli obiektu test (będą prywatne).

Nazwy własności w test[obj1] i test[obj2] ulegną konwersji do ciągu znaków "[object Object]".

Istotne jest aby omyłkowo nie zinterpretować takiego zapisu jako tablicy z elementami object i Object.

"[object Object]" to zwykły ciąg znaków powstający w wyniku konwersji ({}).toString()

Ten sam ciąg znaków użyty dwukrotnie jako nazwa własności obiektu test powoduje, że każde kolejne jego użycie nadpisuje poprzednio zdefiniowaną własność o tej samej nazwie.

test[obj1] i test[obj2] logują do konsoli "Qux" bo taka wartość została przypisana jako ostatnia dla test["[object Object]"].

🎢 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