教学博文,在Js中如何正确的精准的判断数据的数据类型

众所周知,js是一门弱类型的语言,但是弱类型不等于没有类型。数据类型有还是有的,比如数值、字符串、对象、数组...等等,在项目中,因为一些业务上的原因我们需要对数据类型进行一个判断,以走进对应的流程。这个时候我们就需要对数据类型就行一个判断了!

2021-10-25 20-13-42屏幕截图.png

不推荐的方案

很多机智的小可爱应该都是使用 typeof 来判断数据类型的吧!没准一大堆人都还不知道 typeof 是干嘛的。诚然,typeof 虽好,但应用的场景太少了,比较首先,比如我们在常见的 数组和对象 就不能很好的区分!

比如你可以在控制台复制并执行如下代码,你会发现,数组和对象检测出来的结果都是 object

console.log(typeof []); // 返回: object
console.log(typeof {}); // 也返回:object

当然,如果你细心一点你就会发现,typeof null 竟然也是对象!因此,typeof 并不是适用于大多数实操场景,因为在实际的项目中,你可以说 数组、对象、空值都是相当常见的场景,比如商品列表,他就是一个数组的形式;商品详情页,他就是一个对象的形式;同样的,获取不到某些数据,后台给你返回接口的默认值可能就是null,因此,typeof 只时候非常简单的场景,比如字符串数字,如果想要更精确的检查数据类型,那么可以用使用下面的方法!

正确的方法

你可以使用 Object.prototype.toString.call() 这样的方法来判断数据类型,比如就像下面这样...

console.log(Object.prototype.toString.call("字符串")); // 返回: [object String]
console.log(Object.prototype.toString.call(123456)); // 返回: [object Number]
console.log(Object.prototype.toString.call(undefined)); // 返回: [object Undefined]
console.log(Object.prototype.toString.call(null)); // 返回: [object Null]
console.log(Object.prototype.toString.call([])); // 返回: [object Array]
console.log(Object.prototype.toString.call({})); // 返回: [object Object]

当然,不仅仅局限于传统的数据格式,ES6的新数据格式,也是可以正确的判断的哟!

console.log(Object.prototype.toString.call(new Blob([]))); // 返回: [object Blob]
console.log(Object.prototype.toString.call(new Map())); // 返回: [object Map]
console.log(Object.prototype.toString.call(new Set([]))); // 返回: [object Set]

总结

因此,我们可以很轻松的封装一个工具类给自己使用,比如就像下面这样~

(function () {
    /**
     * 基础实例
     * @param {*} params
     */
    function instace(params, type) {
        return Object.prototype.toString.call(params) === type;
    }

    /**
     * 检查数据是否为对象
     * @param {*} params
     * @returns
     */
    function isObject(params) {
        return instace(params, "[object Object]");
    }

    /**
     * 检查数据是否为数组
     * @param {*} params
     * @returns
     */
    function isArray(params) {
        return instace(params, "[object Array]");
    }

    /**
     * 检查数据是否为null
     * @param {*} params
     * @returns
     */
    function isNull(params) {
        return instace(params, "[object Null]");
    }

    /**
     * 检查数据是否为undefined
     * @param {*} params
     * @returns
     */
    function isUndefined(params) {
        return instace(params, "[object Undefined]");
    }

    /**
     * 检查数据是否为字符串
     * @param {*} params
     * @returns
     */
    function isString(params) {
        return instace(params, "[object String]");
    }

    /**
     * 检查数据是否为数值
     * @param {*} params
     * @returns
     */
    function isNumber(params) {
        return instace(params, "[object Number]");
    }

    // 默认注册给 window 对象
    if (typeof window !== "undefined") {
        window.isArray = isArray;
        window.isObject = isObject;
        window.isNull = isNull;
        window.isUndefined = isUndefined;
        window.isString = isString;
        window.isNumber = isNumber;
    }

    // 如果引用了jquery,那么就注册给jquery用
    if (typeof jQuery !== "undefined") {
        $.extend({
            isArray: isArray,
            isObject: isObject,
            isNull: isNull,
            isUndefined: isUndefined,
            isString: isString,
            isNumber: isNumber
        });
    }

    // 如果引入了vue,那么就注册给vue用
    if (typeof Vue !== "undefined") {
        Vue.prototype.isArray = isArray;
        Vue.prototype.isObject = isObject;
        Vue.prototype.isNull = isNull;
        Vue.prototype.isUndefined = isUndefined;
        Vue.prototype.isString = isString;
        Vue.prototype.isNumber = isNumber;
    }
})(window, jQuery, Vue);

当然!现在前端早已不是传统的静态页面了,都是工程化的项目了,对于脚手架项目,你同样可以封装一套自用!就像下面这样~

/**
 * 你可以在人类浏览下引入该js文件后以此输入
 * const check = new Check();
 * check.isArray([]); 
 * 这样的方式来调用这个 class
 * -----
 * 如果是工程化项目,可以把下面这句话放开
 * 可以在底部加一句:export default Check;
 * 如果想更简便一点,可以写成:export default new Check();
 */
class Check {
    constructor() {}

    /**
     * 基础实例
     * @param {*} params
     */
    instace(params, type) {
        return Object.prototype.toString.call(params) === type;
    }

    /**
     * 检查数据是否为对象
     * @param {*} params
     * @returns
     */
    isObject(params) {
        return this.instace(params, "[object Object]");
    }

    /**
     * 检查数据是否为数组
     * @param {*} params
     * @returns
     */
    isArray(params) {
        return this.instace(params, "[object Array]");
    }

    /**
     * 检查数据是否为null
     * @param {*} params
     * @returns
     */
    isNull(params) {
        return this.instace(params, "[object Null]");
    }

    /**
     * 检查数据是否为undefined
     * @param {*} params
     * @returns
     */
    isUndefined(params) {
        return this.instace(params, "[object Undefined]");
    }

    /**
     * 检查数据是否为字符串
     * @param {*} params
     * @returns
     */
    isString(params) {
        return this.instace(params, "[object String]");
    }

    /**
     * 检查数据是否为数值
     * @param {*} params
     * @returns
     */
    isNumber(params) {
        return this.instace(params, "[object Number]");
    }
}