【问题标题】:Is this a good way to identify the type of a javascript object?这是识别 javascript 对象类型的好方法吗?
【发布时间】:2011-02-16 01:46:14
【问题描述】:

显然,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] ) ;
            }

        }

    }

感谢阅读!

【问题讨论】:

    标签: javascript object types


    【解决方案1】:

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

    一个已知问题是它无法在跨框架环境中工作。

    typeof 操作符不是那么有用,并且存在一些实现错误,例如在 Chrome 或 Firefox 2.x 中,RegExp 对象被检测为"function",因为它们使 可调用(例如/foo/(str);)。

    constructor 属性可以被篡改,你不应该永远太信任它。

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

    一些days ago 我正在构建一个简单但强大的类型检测 函数,它使用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();
    }
    

    这个函数的second variant 更加严格,因为它只返回 ECMAScript 规范中描述的内置对象类型。

    可能的输出值:

    原语:

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

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

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

    【讨论】:

    • 你已经赢得了 74K 的声誉,CMS。
    • 好东西。谢谢!您能否详细说明为什么使用constructor 属性不是一个好主意,因为它可能会被“篡改”?
    • @Diobeus,谢谢!,@FK82 我的意思是constructor 属性是可写的,并且格式错误的对象可能会给您错误的结果,例如(var re = /foo/; re.constructor = null;),在自定义类型without even noticing实现继承时,您也可能设置错误的constructor...
    • @CMS 好的,再次感谢。所以,继承搞砸了构造函数。毕竟javascript中没有java,是吗? :-)
    • @FK82:覆盖整个构造函数的prototype 成员可能会破坏constructor 属性...是的,JavaScript 更像是“C 中的 Lisp”:-)
    【解决方案2】:

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

    【讨论】:

    • 看起来类似于 CMS 的技术。
    • 是的。他们似乎都使用相同的机制。还是谢谢。
    猜你喜欢
    • 2011-05-30
    • 2017-02-05
    • 2011-12-31
    • 1970-01-01
    • 2016-03-02
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多