使用 toString 进行类型检测

作者:手气不错 发布时间:January 13, 2009 分类:Javascript

toString 方法返回对象的描述信息,很多时候我们都忘记了还有这属性的存在。在查看 jQuery 源码时,发现其 isArray 竟然令人惊艳的使用 toString 进行类型判断:

597 toString = Object.prototype.toString;
    ...
616 isArray: function(obj) {
617    return toString.call(obj) === "[object Array]";
618 }

Javascript 这种弱类型的脚本语言进行类型检测,是件很头痛的事情。巧合的是 Perfection Kills 近期也发布了篇同内容的文章,并得出相似的结论。

Perfection Kills 还阐述了使用 instanceof 和 typeof 需要格外注意的问题,以及其他如何使用“正统保险”的方法实现 isArray 函数(另,针对 YUI 的 isArray 写法,可以参考这里)。

回到上述 jQuery 代码,Mozilla 针对 toString 的描述道破其中玄机:

If this method is not overridden in a custom object, 
toString returns [object type], where *type* is the object type. 

那么,可以同时 toString 使用针对统一的返回格式进行类型检测。由于 call 的首个参数必须是 Object 类型以及

alert(typeof null);

返回的是 Object (标准如此规定让我很困惑),那么索性针对 undefined 以及 null 独立的判断。根据上述观点实现简单的检测代码如下

var chkType = function (obj) {
    if (obj === null) {
        return 'Null';
    }

    if (obj === undefined) {
        return 'Undefined';
    }

    return Object.prototype.toString.call(obj).match(/s(.+)]$/)[1];
};

最后,简单得写了个 DEMO

已有 2 条回复

  1. wow guide January 14th, 2009 at 12:48 am #1
    wow guide

    学习了~

    mootools 的$type 还是使用 typeof



    function $type(obj){

    if (obj == undefined) return false;

    if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name;

    if (obj.nodeName){

    switch (obj.nodeType){

    case 1: return 'element';

    case 3: return (/S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';

    }

    } else if (typeof obj.length == 'number'){

    return (obj.callee) ? 'arguments' : 'collection';

    }

    return typeof obj;

    };

  2. kele January 16th, 2009 at 02:38 am #2
    kele

    job/season3/

    <dt class="dqa">设计质量工程师</li>

    应该是</dt>

    还有,js里的“/”都要转义。

    疏忽不得啊。

添加新回复

Yahoo 统计