Использование оператора instanceof
в некоторых случаях недостаточно .
Известной проблемой является то, что он не работает в кросс-фреймовых средах.
Оператор typeof
не очень полезен, и есть некоторые ошибки реализации, например, как в Chrome или Firefox 2.x, где RegExp
объекты обнаруживаются как "function"
, потому что они сделали вызываемый (например, /foo/(str);
).
Свойство constructor
может быть подделано , и вы должны никогда не доверять ему.
И, наконец, метод Function.prototype.toString
зависит от реализации , что означает, что реализация может не включать даже имя функции в строковое представление функция ...
Несколько дней назад Я строил простую, но надежную функцию обнаружения типа , она использует typeof
для примитивных значений и использует [[Class]]
внутреннее свойство для объектов.
Все объекты обладают этим свойством, реализации используют его внутренне для обнаружения вида объекта, он полностью неизменен и доступен только через Object.prototype.toString
метод:
Использование:
//...
if (typeString(obj) == 'array') {
//..
}
Реализация:
function typeString(o) {
if (typeof o != 'object')
return typeof o;
if (o === null)
return "null";
//object, array, function, date, regexp, string, number, boolean, error
var internalClass = Object.prototype.toString.call(o)
.match(/\[object\s(\w+)\]/)[1];
return internalClass.toLowerCase();
}
Второй вариант этой функции *1057* является более строгим, поскольку он возвращает только встроенные типы объектов, описанные в спецификации ECMAScript.
Возможные выходные значения:
Примитивы:
"number"
"string"
"boolean"
"undefined"
"null"
"object"
Встроенные типы объектов (через [[Class]]
)
"function"
"array"
"date"
"regexp"
"error"