W JavaScript wszystko jest obiektem (lub przynajmniej może być traktowane jako obiekt), z wyjątkiem prymitywów (booleany, null, liczby, łańcuchy i wartość undefined
(i symbol w ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
Jak widać obiekty, tablice i wartość null
są uważane za obiekty ( null
jest odniesieniem do obiektu, który nie istnieje). Funkcje są rozróżniane, ponieważ są specjalnym rodzajem obiektów, które można wywoływać . Jednak nadal są obiektami.
Z drugiej strony literały true
, 0
, ""
a undefined
nie obiektów. Są to prymitywne wartości w JavaScript. Jednak logicznych, liczby i ciągi mają także konstruktorów Boolean
, Number
a String
odpowiednio który owinąć swoje odpowiednie prymitywów, aby zapewnić dodatkową funkcjonalność:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
Jak widać, gdy prymitywne wartości są zawinięte w odpowiednio Boolean
, Number
i String
konstruktory stają się obiektami. instanceof
Operator działa tylko dla obiektów (dlatego wraca false
do wartości pierwotnych):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
Jak widać oba typeof
i instanceof
są niewystarczające do sprawdzenia, czy wartość jest wartością logiczną, liczbą lub łańcuchem - typeof
działa tylko dla prymitywnych boolanów, liczb i łańcuchów; i instanceof
nie działa dla prymitywnych boolanów, liczb i łańcuchów.
Na szczęście istnieje proste rozwiązanie tego problemu. Domyślna implementacja toString
(tzn. Jak jest natywnie zdefiniowana Object.prototype.toString
) zwraca wewnętrzną [[Class]]
właściwość zarówno pierwotnych wartości, jak i obiektów:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
Wewnętrzna [[Class]]
właściwość wartości jest znacznie bardziej użyteczna niż typeof
wartość. Możemy użyć Object.prototype.toString
do stworzenia własnej (bardziej użytecznej) wersji typeof
operatora w następujący sposób:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
Mam nadzieję, że ten artykuł pomógł. Aby dowiedzieć się więcej o różnicach między prymitywami a opakowanymi obiektami, przeczytaj następujący post na blogu: Sekretne życie prymitywów JavaScript