Это хороший способ определить тип объекта JavaScript?

Видимо ни instanceof ни typeof поставить с точки зрения правильной идентификации типа каждого объекта JavaScript. Я придумал эту функцию, и я жду обратной связи:

    function getType() {

        var input = arguments[0] ;

        var types = ["String","Array","Object","Function","HTML"] ; //!! of the top of my head

        for(var n=0; n < types.length; n++) {

            if( input.constructor.toString().indexOf( types[n] ) != -1) {
                document.write( types[n] ) ;
            }

        }

    }

Спасибо за прочтение!

2 ответа

Решение

Опираясь на 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();
}

Второй вариант этой функции является более строгим, поскольку он возвращает только встроенные типы объектов, описанные в спецификации ECMAScript.

Возможные выходные значения:

Примитивы:

  • "number"
  • "string"
  • "boolean"
  • "undefined"
  • "null"
  • "object"

Встроенные типы объектов (через [[Class]])

  • "function"
  • "array"
  • "date"
  • "regexp"
  • "error"

Подобный вопрос возник несколько дней назад. Я взломал jQuery 1.4.2, чтобы посмотреть, как это было сделано. Вот мои результаты на данный момент, вы можете запустить проверки для остальных из них я уверен:

(function() {

    // Define the base sys namespace
    this.sys = function() { };

    var toString = Object.prototype.toString;

    //from jQuery 1.4.2    
    sys.isFunction = function(obj) {
        return toString.call(obj) === "[object Function]";
    }

    //from jQuery 1.4.2
    sys.isArray = function(obj) {
        return toString.call(obj) === "[object Array]";
    }
}

Использование:

if (sys.isArray(myObject)) doStuff();
Другие вопросы по тегам