史上最详细JS数据类型检测

目录

一、typeof

二、instanceof

三、constructor

四、 Object.prototype.toString.call()


一、typeof

       1. 直接在计算机底层基于数据类型的值(二进制)进行检测。

        2.对象存储在计算机中都是以000开始的二进制存储方式,null也是,所以检测出来的结果是‘object’。

console.log(typeof null) //object

        3.typeof只能检测基本数据类型 对于普通对象、数组对象、正则对象、日期对象 返回的结果都是‘object’

let obj = {a:1}
let obj1 = [{a:1}]
let obj2 = /^0-9/
let obj3 = new Date()
//普通对象
console.log(typeof obj)//object
//数组对象
console.log(typeof obj1)//object
//正则对象
console.log(typeof obj2)//object
//日期对象
console.log(typeof obj3)//object

二、instanceof

        1.低层机制:检测当前实例是否属于这个类,只要当前类出现在实例的原型链上,检测结果都返回true。

let arr = []
console.log(arr instanceof Array)//true
console.log(arr instanceof RegExp)//false
//Object出现在arr的原型链上、所以结果为true
console.log(arr instanceof Object)//true

        2.存在问题:由于我们可以肆意修改原型的指向,所以检测出来的结果是不准的。

function Fn() {
    this.x = 10
}
Fn.prototype = Object.create(Array.prototype)
let f = new Fn()
//由于我们修改了Fn的原型指向,所以最后Fn的实例指向Array为true
console.log(f instanceof Array) //true

        3.缺点:instanceof不能用于检测基本数据类型。

//不能用于检测基本数据类型
console.log(1 instanceof Number) //false

        4.仿写instanceof:本质就是实例.__proto__ === 类.prototype

function myInstanceof(example,classFunc) {
    //获取类的prototype
    let calssFuncPrototype = classFunc.prototype
    //获取实例的__proto__
    let exampleProto = Object.getPrototypeOf(example)
    while(true) {
        //判断实例的__proto__是否等于null,即是否查找到了原型链的最顶层
        if (exampleProto == null) {
            return false
        }
        //判断实例的__proto__是否等于类的prototype
        if (exampleProto == calssFuncPrototype) {
            return true
        }
        //继续向顶层获取实例的__proto__
        exampleProto = Object.getPrototypeOf(exampleProto )
    }
}

let arr = []
console.log(myInstanceof(arr,Array))//true
console.log(myInstanceof(arr,Object))//true
console.log(myInstanceof(arr,Function))//false

三、constructor

        1.优点:对比instanceof,constructor可以检测基本数据类型;也不会顺着原型类查找

let arr = []
let num = 1
//可以判断基本数据类型
console.log(num.constructor == Number)//true
console.log(arr.constructor == Array)//true
//不会顺着原型链查找
console.log(arr.constructor == Object)//false
console.log(arr.constructor == RegExp)//true

        2.缺点:可以修改constructor,导致判断不准确。

Number.prototype.constructor = 'AA'
let num = 1
console.log(num.constructor === Number)//false

四、 Object.prototype.toString.call()

        1.标椎检测数据类型的方法:Object.prototype.toString()不是转换成字符串,而是返回当前实例所属类的信息。

        2.返回结果以"[object 数据类型]",其中数据类型有Number、String、Boolean、Null、Undefined、Symbol、Object、Array、RegExp、Date、Function......。

        3.检测方式:使用call将Object.prototype.toString()方法中的this指向你要检测的值,就能返回当前值所属类的信息。

let obj = {name:1}

console.log(Object.prototype.toString.call(obj))//"[object Object]"

        4.手写万能检测方法 toType()

let classType = {}
let toString = classType.toString//=>Object.prototype.toString

//设定数据类型映射表
let arrAll = ["Boolean","Number","String","Object","Function","Error","Date","Symbol","RegExp","Array"]

//循环映射表为classType添加属性
arrAll.forEach(name=>{
    classType[`[object ${name}]`] = name.toLowerCase()
})

function toType(obj) {
    //判断 null undefined
    if (obj == null) {
        return obj + ''
    }
    //判断是否为object或function 是则使用classType判断 否则使用typeof
    return typeof obj === 'object' || typeof obj === 'function' ? classType[toString.call(obj)] || 'object' : typeof obj
}

let arr = []
console.log(toType(arr))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值