下面介绍了三种 JavaScript 中常用的类型判断方法。

typeof

typeof 是一个一元操作符,返回操作数的类型:

typeof undefined;        // 'undefined'
typeof 1;                // 'number'
typeof 'a';              // 'string'
typeof true;             // 'boolean'
typeof function() {};    // 'function'
typeof null;             // 'object'
typeof {};               // 'object'

不过 typeof 只会识别一些基础类型(也就是上面这几种类型),
而除函数外的其它对象,包括 null,都只是返回的 object

typeof [];               // 'object'
typeof /[a-z]+/g;        // 'object'

instanceof

instanceof 是一个二元操作符,其左操作数是一个对象,右操作数是一个类函数,
如果这个对象是该类函数或其子类所创建的实例,则会返回 true,否则返回 false。

1 instanceof Number;               // false
new Number(1) instanceof Number;   // true
['a', 'b'] instanceof Array;       // true

需要明确的是,instanceof 并不是判断对象的类型,
而是判断对象是不是某个类函数所创建的实例。
比如如果一个页面中含有一个子页面(iframe),而父页面和子页面的 JavaScript 运行时环境是不同的,
所以若是用在子页面中创建的数组对象与父页面中的 Array 构造函数做判断,就会返回 false
因为子页面中的数组对象并不是由父页面中的 Array 构造函数创建的。

类属性

类属性是一个包含类型信息的字符串,其格式是固定的,它不能被修改,且只能通过 Object 默认的 toString() 方法得到。
因此,如果要判断一个对象的类型,便可以使用该方法:

var toString = Object.prototype.toString;

toString.call(1);             // '[object Number]'
toString.call(new Date());    // '[object Date]'
toString.call([]);            // '[object Array]'
toString.call(/[a-z]+/g);     // '[object RegExp]'

另外,为了使用方便,一般会抽象出来如下几个方法:

var _toString = Object.prototype.toString,
    typemap = {
        '[Object Array]': 'array',
        '[Object Date]': 'date',
        '[Object RegExp]': 'regexp'
    };

function getClassInfo(obj) {
    return typemap[toString.call(obj)];
}

function isArray(obj) {
    return getClassInfo(obj) === 'array';
}

function isDate(obj) {
    return getClassInfo(obj) === 'date';
}

function isRegExp(obj) {
    return getClassInfo(obj) === 'regexp';
}