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