Bug #048
🪲 Znajdź buga
console.log({} instanceof Object)
console.log([] instanceof Array)
console.log([] instanceof Object)
console.log((() => {}) instanceof Function)
console.log((() => {}) instanceof Object)
console.log("foo" instanceof String)
console.log(String("foo") instanceof String)
console.log(new String("foo") instanceof String)
console.log("foo" instanceof Object)
console.log(String("foo") instanceof Object)
console.log(new String("foo") instanceof Object)
Czy w JavaScript wszystko jest obiektem?
Jakie wartości logiczne zostaną zalogowane do konsoli dla poszczególnych wywołań instanceof
?
🧪 Rozwiązanie
console.log({} instanceof Object) // true
console.log([] instanceof Array) // true
console.log([] instanceof Object) // true
console.log((() => {}) instanceof Function) // true
console.log((() => {}) instanceof Object) // true
console.log("foo" instanceof String) // false
console.log(String("foo") instanceof String) // false
console.log(new String("foo") instanceof String) // true
console.log("foo" instanceof Object) // false
console.log(String("foo") instanceof Object) // false
console.log(new String("foo") instanceof Object) // true
Można by błędnie założyć, że instanceof
sprawdza czy obiekt został utworzony przez dany konstruktor, czyli, czy jego instancja została utworzona poprzez wywołanie new
na funkcji konstruującej obiekt.
W rzeczywistości instanceof
sprawdza jednak, czy utworzona instancja obiektu ma w całym swoim łańcuchu prototypów dany konstruktor.
W JavaScript obiekty dziedziczą po sobie przekazując swoje prototypy, jednocześnie tworząc łańcuch, w którym "foo".__proto__.constructor
zwróci String
, a "foo".__proto__.__proto__.constructor
zwróci Object
.
Ciąg znaków dziedziczy więc w łańcuchu prototypów zarówno konstruktor String
, jak i Object
.
Podobnie wygląda sytuacja w przypadku innych typów danych.
Obiekt daty będzie miał w swoim łańcuchu prototypów zarówno konstruktor Date
, jak i Object
.
Tablica (array) również będzie miała w swoim łańcuchu prototypów konstruktor Array
, jak i Object
.
Funkcja również, Function
i Object
.
Nie bez powodu mówi się, że w JavaScript wszystko jest obiektem.
Typy prymitywne (jak np. ciąg znaków) z użyciem instanceof
nie będą się jednak przedstawiały jako instancje Object
, mimo, że w łańcuchu prototypów jasno widać, że "foo".__proto__.__proto__.constructor
to Object
.
NaN
również nie przedstawi się jako instancja obiektu, ale w swoim łańcuchu prototypów ma konstruktor Number
i Object
.
Podobnie w przypadku wartości logicznych true
i false
. Tak jak wartości prymitywne, nie zgłoszą się one jako instancja obiektu, ale mają w swoim łańcuchu prototypów konstruktory Boolean
i Object
.
Jedynie wartości null
i undefined
nie mają swoich prototypów i konstruktorów, ale żeby było śmieszniej typeof null
zwróci object
. Jest to jednak uznawane za znany bug w języku JavaScript i ze względu na zachowanie kompatybilności wstecznej, nie zostaje naprawiany.
🎢 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