数组类型检测的底层机制

  1. 数据类型检测
    (1)typeof 检测数据类型的运算符
    返回结果是一个字符串,字符串中包含了对应的数据类型" number/string/boolean/undefined/symbol/bigint/object/function" =>typeof typeof xxx 结果都是"string"
    存在的BUG
    typeof的原理:按照计算机底层存储的二进制结果进行检测的,对象都是以000…开始的。
    typeof null “object” =>null的二进制存储值000。
    所有对象都是以000开始的,所以基于typeof检测的结果都是"object",也就是typeof无法细分是普通对象还是数组等对象。
    (2)instanceof 并不是用来检测数据类型的,是用来检测当前实例是否属于这个类。
    用它来检测,一般只应用于普通对象/数组对象/正则对象/日期对象等的具体细分。
    <script>
        //instanceof实例
        let arr=[];
        console.log(arr instanceof Array);  //true
        console.log(arr instanceof Object); //true 不能证明 xxx instanceof Object 是true就是普通对象
        console.log(arr instanceof RegExp); //false
    </script>

instanceof无法应用到原始值类型数值的检测上

        let n=10;
        let m=new Number(10);
        console.log(n.toFixed(2)); //"10.00" n是Number类的实例,只不过它是字面量方式创造出来的原始值而已(其实n.toFixed(2)的时候,n这个基本类型值浏览器内部也会把它Object(n)一下,然后在调用方法,此时它就具备了__proto__)
        console.log(m.toFixed(2)); //"10.00" m也是Number类的实例,只不过它是构造函数方式创造出来的引用类型值而已
        console.log(n instanceof Number); //false
        console.log(m instanceof Number); //true

原理:
//基于“实例 instanceof 类”检测的时候,浏览器底层是这样处理的“类Symbol.hanInstance
//Function.prototype[Symbol.hasInstance]=function Symbol.hasInstance{[native code]}
//Symbol.hasInstance方法执行的原理
//根据当前实例的原型链上(proto)是否存在这个类的原型(prototype)
//arr.proto===Array.prototype =>arr instanceof Array :true
//arr.proto.proto===Object.prototype =>arr instanceof Object : true

        let arr=[];
        console.log(arr instanceof Array);  //true
        console.log(arr instanceof Object); //true
        console.log(Array[Symbol.hasInstance](arr)); //true
        //===========
        let obj={}
        console.log(arr instanceof obj); //报错 因为obj是一个对象,它没有[Symbol.hasInstance]这个属性(函数才可以调用Function.prototype上的这个方法)

(3)constructor:获取实例的构造函数,但是也是可以随意被更改的

       let arr=[];
        console.log(arr.constructor=== Array);  //true
        console.log(arr.constructor===Object); //false

(4)Object.prototype.toString.call:专门用来检测数据类型的。
专门用来检测数据类型的
Number/String/Boolean/Symbol/BigInt/Array/RegExp/Date/Function/Object…的原型上都有toString,除了Object.prototype.toString不是转换为字符串,其余都是,Object.prototype.toString是用来检测数据类型的。
返回结果"[object 对象[Symbol.toStringTag || 对象.构造函数 || Object]

  1. 重写instanceof
       //obj要检测的实例对象(不支持原始值类型)
        //constructor要检测的类(必须是一个函数)
        function instance_of(obj,constructor){
            //参数校验
            if(obj==null||!/^(object|function)$/i.test(typeof obj)) return false;
            if(typeof constructor!=="function") throw new TypeError("Right-hand side of 'instanceof' is not callable");
            //obj.__proto__=Object.getPrototypeOf(obj)
            let proto=Object.getPrototypeOf(obj),
                prototype=constructor.prototype;
            while(true){
                //找到Object.prototype.__proto__都没有相等的,则证明不是当前类的实例
                if(proto===null) return false;
                //找到对象的原型链包含类的原型,则证明对象是类的一个实例
                if(proto===prototype) return true;
                //一级级查找即可
                proto=Object.getPrototypeOf(proto);
            }
        }
        console.log(instance_of([],Array)); //true
        console.log(instance_of([],Object));//true
        console.log(instance_of([],RegExp));//false
        console.log(instance_of(10,Number));//false
        console.log(instance_of(new Number(10),Number)); //true
        console.log(instance_of([],{}));//报错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值