Przejdź do głównej zawartości

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