Это хороший способ определить тип объекта JavaScript? - PullRequest
2 голосов
/ 05 мая 2010

Очевидно, что ни 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 ]

3 голосов
/ 05 мая 2010

Использование оператора 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"
1 голос
/ 05 мая 2010

Подобный вопрос возник несколько дней назад. Я взломал 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...