这是识别javascript对象类型的好方法吗?

时间:2010-05-05 18:24:30

标签: javascript object types

显然,instanceoftypeof都无法正确识别每个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 个答案:

答案 0 :(得分:3)

在某些情况下,依赖instanceof运算符为not good enough

一个已知问题是它不适用于跨框架环境。

typeof运算符不太有用,并且存在一些实现错误,例如在Chrome或Firefox 2.x中,其中RegExp个对象被检测为"function",因为他们已经可赎回(例如/foo/(str);)。

constructor属性可以被篡改,你永远不会对它充满信任。

最后,Function.prototype.toString方法依赖于实现,这意味着实现可能甚至不包括函数字符串表示中的函数名。 ..

一些days ago我正在构建一个简单但强大的类型检测函数,它使用typeof作为原始值,并依赖于[[Class]]内部属性对象。

所有对象都具有此属性,实现在内部使用它来检测对象的,它完全是不可变的,并且只能通过{{3}访问方法:

用法:

//...
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();
}

此函数的Object.prototype.toString更严格,因为它只返回ECMAScript规范中描述的内置对象类型。

可能的输出值:

<强>基元:

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

内置对象类型(通过[[Class]]

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

答案 1 :(得分:1)

几天前出现了类似的问题。我破解了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();