Object.prototype.toString.call

SnoopySnoopy

Object.prototype.toString.call^1 je metoda která vrací reprezentaci datového typu daného objektu. Pojďme si takovové složité volání neprve rozebrat.

Nejspíše víte, že základní objekt Objekt obsahuje metodu toString, která se automaticky volá, když je třeba převést objekt na primitivní hodnotu. Každý další objekty pak mají vždy prototypovou referenci na Object.prototype, který obsahuje tuto toString metodu.

V JS pak mohou mít libovolné objekty své vlastní metody, i když je jejich název shodný s názvem metody z jejich nadtřídy. Tedy když zavoláte toString, začne JavaScriptový engine hledat, zda má toString ve svém scope a pokud ho najde znemožním tím volat původní Object.prototype.toString.

Proto nám volání Object.prototype zaručuje, že zavoláme metodu kterou pro tento účel skutečně chceme. Nad metodou toString pak používáme volání "call", která umožňuje změnit kontext volání na zadaný objekt. Tím, že se v call změní na specifický objekt, který chceme zjistit jeho typ.

Rozdíl toString mezi typeof

Kromě toho, že název volání je 6x delší. Tato metoda nám poskytuje u objektových datových typů víc informací. V případě primitivních datových typů se chová stejně, ale pro typeof je každý objekt jen Object.

typeof []; // object
typeof {}; // object
typeof /regex/; // object
typeof function () {}; // function

Mít víc informací je užitečné pro ladění kódu a pro zjišťování typů objektů, se kterými pracujete. Některé build-in funkce mají vlastní přizpůsobenou metodu toString, například Math a HTMLDocument.

Object.prototype.toString.call([]) // [object Array]
Object.prototype.toString.call({}); // [object Object]
Object.prototype.toString.call(/regex/); // [object RegExp]
Object.prototype.toString.call(function () {}); // [object Function]
Object.prototype.toString.call(new Date); // [object Date]

Funguje konzistentne i pro null a undefined i přes to, že nemají kontruktory.

Object.prototype.toString.call(null) // [object Null]
Object.prototype.toString.call(undefined); // [object Undefined]

Vlastní string tag

Symbol toStringTag nám umožňuje nastavit vlastní hodnotu, která se vrátí při volání metody Object.prototype.toString(). Používá se takto:

class Animal {
  get [Symbol.toStringTag]() {
    return 'Animal';
  }
}

console.log(Object.prototype.toString.call(new Animal())); // Výstup: "[object Animal]"

Popřípadě můžeme nastavit i následovně

Object.defineProperty(MyClass.prototype, Symbol.toStringTag, {
  value: 'MyClass',
});

Užitečný alias

Často je praktické vytvořit si kratší alias k této metodě, která nám vrátí jen typ

function isType(obj) {
	return Object.prototype.toString.call(obj).slice(8,-1)
}