Определение типов/классов в JavaScript

Сводные таблички к статье JavaScript, typeof, типы и классы.

typeof value

Значение typeof Примечания
Number number включая NaN и Infinity
Boolean boolean
String string
null object в ES5.1 будет заменён на "null"
undefined undefined
Function function в IE 6,7,8 typeof alert === "object"
(вообще любая host-функция, например, document.getElementById)
всё остальное object Safari: typeof HTMLCollection === "function"
Chrome <=12: typeof regexp === "function".

Объекты-обёртки над примитивными значениями, созданные через new всегда "object":

new Number(1) object
new Boolean(true) object
new String("string") object

Без new результат корректный, так как возвращается скаляр:

Number(1) number
Boolean(true) boolean
String("string") string

Object.prototype.toString.call(value)

Значение typeof Примечания
Number [object Number] включая NaN и Infinity
Boolean [object Boolean]
String [object String]
null [object Null] Firefox 3: [object Window]
IE < 9: [object Object]
Opera < 11: [object Window]
undefined [object Undefined] Firefox 3: [object Window]
IE < 9: [object Object]
Opera < 11: [object Window]
Function [object Function] IE 6, 7, 8 для alert: [object Object]
Array [object Array]
RegExp [object RegExp]
Error [object Error] в том числе и производные SyntaxError, TypeError...
arguments [object Arguments] IE < 9, Firefox 3, Opera 10: [object Object]
DOMElement (DIV) [object HTMLDivElement] Для каждого тега свой
IE < 9: [object Object]
TextNode [object Text] IE < 9: [object Object]
HTMLCollection [object HTMLCollection] (Firefox, IE 9)
[object NodeList] (Chrome, Opera, Safari)
[object Object] (IE < 9)
остальные объекты [object Object]

Конструкторы built-in объектов

Значение constructor === (*) instanceof (**) constructor.name (***)
Number Number да нет "Number"
Boolean Boolean да нет "Boolean"
String String да нет "String"
Function Function да да "Function"
null нет
undefined нет
Array Array да да "Array"
Object
(простой {})
Object да да "Object"
Date Date да да "Date"
RegExp RegExp да да "RegExp"
Arguments Object "Object"

* ===: можно ли определить тип сравнением с конструктором ("string".constructor === String)

** instanceof: можно ли для определения типа использовать instanceof (!("string" instanceof String))

***: в IE (во всех включая 9-й) нет constructor.name в остальных браузерах работает нормальноp

Конструкторы host-объектов

Здесь компактной табличкой не обойдёшься.

IE

В IE (до 7-й версии включительно) у DOM-объектов вообще нет конструкторов.

Ниже под фразой «во всех браузерах» подразумевается «во всех, кроме IE <= 7».

constructor.name

constructor.name DOM-объектов содержит нечто вменяемое только у Chrome. В остальных браузерах, либо вообще нет свойства, либо в нём какая-то ересь.

DOM-элемент

У каждого тега свой конструктор: HTMLDivElement, HTMLSpanElement. Однако, все они наследуются от HTMLElement. Следующий код позволяет определить DOM-элемент во всех браузерах (IE > 8 *):

var element = document.createElement("div");
element instanceof HTMLElement; // true

(*) В IE8 появляются конструкторы у host-объектов, а также нижеприведённые глобальные конструкторы Text, HTMLCollection. Но вот HTMLElement там ещё нет.

TextNode

Определение TextNode во всех браузерах:

var textNode = document.createTextNode("text");
textNode instanceof Text; // true

При этом попытка вывести textNode.constructor.toString() может привести в замешательство:

В Safari это будет TextConstructor, но всё равно доступный через глобальную переменную Text.

В Oper'е раньше 10-й конструктором вообще будет Object, но всё равно работает instanceof Text.

HTMLCollection

Определение HTMLCollection во всех браузерах:

var collection = document.getElementsByTagName("div");
(collection instanceof HTMLCollection) || (collection instanceof NodeList);

Во всех браузерах есть, как глобальный объект HTMLCollection, так и NodeList. Однако в каждом браузере коллекция наследуется от одного из них:

HTMLCollection: (Firefox, IE 8+).
NodeList: (Chrome, Opera, Safari).

При этом collection.constructor.toString() также, как и с текстовой нодой может давать разные результаты: NodeListConstructor (Safari), Object (Firefox < 11, Opera < 11).

Также не следует полагаться на прямое сравнение с конструктором: collection.constructor === HTMLCollection.

IE < 8 и host-объекты

В IE host-объекты можно определять только по наличию в них специфических свойств.

value.nodeType === 1; // DOM-Element
value.nodeType === 3; // TextNode
typeof value.length === "number"; // HTMLCollection

Хорошим свидетельством того, что это именно host-объект, а не какой-либо пользовательский объект со свойством nodeType, служит отсутствие в нём свойств constructor и toString.

host-функции (alert, document.getElementById и т.д.) можно идентифицировать по их строковому представлению. Там будет что-нибудь вроде function alert() { [native code] }:

if (("" + value).indexOf("function") !== -1) {
    // value is function
}

У host-функций нет даже метода toString(), но вполне срабатывает приведение к строке через ("" + value).