js中判断数据类型的方法总结

148 阅读2分钟

判断数据类型的方法

  • typeof

    // 底层原理:直接在计算机底层基于数据类型的值(二进制)进行检测
    
    > typeof null
    > "object"   // 因为object底层是以000开头的,null底层就是000,所以是object
    > typeof 普通对象/数组对象/正则对象/日期对象   > "object"
    
    用于检测基本数据类型
    
  • instanceof

    // 底层原理:只要当前类出现在实例的原型链上,结果都为true
    
    例子1
    > let arr = []
    > console.log(arr instanceof Array)  //=>true
    > console.log(arr instanceof RegExp) //=>false
    > console.log(arr instanceof Object) //=>true  为啥为true?因为instancof的底层原理
    
    例子2
    function Fn() {
        this.value = 100;
    }
    Fn.prototype = Object.create(Array.prototype);
    let f = new Fn();
    console.log(f instanceof Array); //=>true 可以随便修改原型链,导致判断不正确
    
    // 不能检测基本数据类型,用于检测Object
    
    // 自己写个instance_of
    /**
     *
     * @param {example} 要检测的值
     * @param {classFn} 检测的类型
     */
    // 实例.__proto__===类.prototype
    // 思路就是先获取 类的prototype,再遍历 实例.__proto__
    // 如果找到 实例.__proto__===类.prototype,返回true
    // 如果找到最后也没找到,则返回false
    // __proto__  IE下不兼容,所以用 Object.getPrototypeOf()
    // Object.getPrototypeOf(example) = example.__proto__
    
    function instance_of(example, classFn) {
        let classFnPrototype = classFn.prototype;
        let proto = Object.getPrototypeOf(example);
        while (true) {
            if (proto === null) {
                // Object.prototype.__proto__ => null
                return false;
            } else if (proto === classFnPrototype) {
                return true;
            }
            proto = Object.getPrototypeOf(proto);
        }
    }
    
    let arr = [];
    console.log(instance_of(arr, Array)); // true
    console.log(instance_of(arr, RegExp)); // false
    console.log(instance_of(arr, Object)); // true
    
  • constructor

    // 看似比instanceof好用一些(基本类型支持)
    
    > Number.prototype.constructor='AA'
    > let n = 1;
    > console.log(n.constructor)  //'AA'
    > console.log(n.constructor === Number);//false constructor也可以随便改,结果也不准
    
    
  • Object.prototype.toString.call()

    // 检测数据类型的标准方法
    // Object.prototype.toString 不是转换为字符串,是返回当前实例所属类的信息
    [object Number/String/Boolean/Null/Undefined/Symbol/Object/Array/RegExp/Date/Function]
    
    console.log(Object.prototype.toString.call(example).substr(8).slice(0,-1))
    

封装检测类型方法

思路:基本类型(除了null)用typeof,其他用Object.prototype.toString.call()

(function () {
    var class2type = {};
    var toString = class2type.toString; //=>Object.prototype.toString

    // 设定数据类型的映射表
    [
        "Boolean",
        "Number",
        "String",
        "Function",
        "Array",
        "Date",
        "RegExp",
        "Object",
        "Error",
        "Symbol",
    ].forEach((name) => {
        class2type[`[object ${name}]`] = name.toLowerCase();
    });

    function toType(obj) {
        // null 或 undefined
        if (obj == null) {
            return obj + "";
        }

        return typeof obj === "object" || typeof obj === "function"
            ? class2type[toString.call(obj)] || "object"
            : typeof obj;
    }
    window.toType = toType;
})();

> toType([])
> "array"