FED

©FrontEndDev.org
2015 - 2024
web@2.23.0 api@2.21.1

一行代码实现数据类型判断

JS 判断数据类型,方法有很多,如 typeof、constructor、toString 等等,甚至可以使用 jQuery 内部的 $.type 都可以判断。其中 typeof 等的判断局限性都比较大,如 typeof 只能判断数据存储类型,constructor 只能判断数据的原型,toString 相对比较完整一点,但显示不够友好,在 jQuery 中对其做了一些修饰,正是Object.prototype.toString的功劳。

Object.prototype.toString.call(1)
// "[object Number]"

Object.prototype.toString.call('1')
// "[object String]"

Object.prototype.toString.call({})
// "[object Object]"

Object.prototype.toString.call([])
// "[object Array]"

Object.prototype.toString.call(window)
// "[object global]"

注意到了吗?每个数据类型的返回值都有一个相同点,那就是[object ,通过取值后面的文字可以获取到该对象的数据类型。即:

Object.prototype.toString.call(object).slice(8, -1).toLowerCase();

Object.prototype.toString.call(1).slice(8, -1).toLowerCase();
// "number"

Object.prototype.toString.call('1').slice(8, -1).toLowerCase();
// "string"

Object.prototype.toString.call({}).slice(8, -1).toLowerCase();
// "object"

Object.prototype.toString.call([]).slice(8, -1).toLowerCase();
// "array"

Object.prototype.toString.call(window).slice(8, -1).toLowerCase();
// "global"

初始的typeis就是这样的:

/**
 * 判断数据类型
 * @param obj {*} 任何数据
 * @returns {string}
 */
var typeis = function (obj) {
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
};

通过测试可知:

typeis(NaN);
// "number"

不太符合预期,需要额外判断一次

/**
 * 判断数据类型
 * @param obj {*} 任何数据
 * @returns {string}
 */
var typeis = function (obj) {
    var ret = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();

    if(isNaN(obj) && ret === 'number'){
        return 'nan';
    }

    return ret;
};

判断 element 元素的时候:

typeis(document.body)
// "htmlbodyelement"
typeis(document.head)
// "htmlheadelement"

不符合预期,再修改:

/**
 * 判断数据类型
 * @param obj {*} 任何数据
 * @returns {string}
 */
var typeis = function (obj) {
    var ret = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();

    if (isNaN(obj) && ret === 'number') {
        return 'nan';
    } else if (/element/.test(ret)) {
        return 'element';
    }

    return ret;
};

最后再对一些全局对象,做些处理:

/**
 * 判断数据类型
 * @param obj {*} 任何数据
 * @returns {string}
 */
var typeis = function (obj) {
    var udf = 'undefined';
    
    if (typeof obj === udf) {
        return udf;
    } else if (typeof window !== udf && obj === window) {
        return 'window';
    } else if (typeof global !== udf && obj === global) {
        return 'global';
    } else if (typeof document !== udf && obj === document) {
        return 'document';
    } else if (obj === null) {
        return 'null';
    }
    
    var ret = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();

    if (isNaN(obj) && ret === 'number') {
        return 'nan';
    } else if (/element/.test(ret)) {
        return 'element';
    }

    return ret;
};

一个比较完善、完整的 typeis 就出来了。