js数据类型判断

99 阅读1分钟

一.typeof判断类型

1.直接在计算机底层基于数据类型的值(二进制)进行检测
2.typeof null "object"  对象存储在计算机中,都是以000开始的二进制存储,null也是,所以检测出来的结果是对象
3.typeof 普通对象/数组对象/正则对象/日期对象 检测都是“object
console.log(typeof 1) // number
console.log(typeof '1') // string
console.log(typeof true) // boolean
console.log(typeof undefined) // undefined
console.log(typeof null) // object
console.log(typeof Symbol(1)) // symbol
console.log(typeof 11111n) // bigint
console.log(typeof function(){}) // function
console.log(typeof new Date()) // object
console.log(typeof /^$/) // object
console.log(typeof {}) // object
console.log(typeof []) // object

二. instanceof判断类型

`instanceof`** **运算符**用于检测构造函数的 `prototype` 属性是否出现在某个实例对象的原型链上。
 1.底层机制:只要当前类出现在实例的原型链,结果都是true
 2.由于我们可以肆意的修改原型的指向,所以检测出来的结果不准确
 3.不能检测基本数据类型
 let arr = []
 console.log(arr instanceof Array) // true
 console.log(arr instanceof Object) // true arr最顶层是object
 console.log(arr instanceof RegExp) // false 
 // 缺点是arr的原型对象可以随时更改
 
 arr.__proto__ = RegExp.prototype
 console.log(arr instanceof Array) // false
 console.log(arr instanceof Object) // true 
 console.log(arr instanceof RegExp) // true 

手写一下instanceof可能更容易看懂🤔

function instance_of(example,classFunc){
    // proto 拿到第一位参数的__proto__  classFuncProto拿到数据类型实例的prototype
    // Object.getPrototypeOf(example)相当于 example.__proto__
    let proto = Object.getPrototypeOf(example),
    classFuncProto = classFunc.prototype
    
    // 循环对比example原型链上否出现在这个实例原型对象
    while(true){
        // 原型比较相同返回
        if(classFuncProto === proto) {
            return true
        }
        // proto到最顶层时,返回false
        if(proto === null) {
            return false
        }
        proto = Object.getPrototypeOf(proto)
    }
}

三.constructor判断类型

1.用起来看似比instanceof好用一些(基本类型支持)
2.选用的是当前prototype的constructor,
3.constructor属性可以随便改,所以也不准
let arr = []
let n =1
console.log(arr.constructor === Array) // true
console.log(arr.constructor === Object) // false
console.log(arr.constructor === RegExp) // false
console.log(n.constructor === Number) // Number

// 缺点
Array.prototype.constructor = '11'
console.log(arr.constructor === Array) // false

四.Object.prototype.toString.call()

1.标准的类型数据检测方法:Object.prototype.toString是返回当前势力所属类的信息
2.检测方法:"[object Number/String/Boolean/Null/undefined/Function/Symbol/Object/Array/Date/RegExp]"
console.log(Object.prototype.toString.call([])) // '[object Array]'
console.log(Object.prototype.toString.call({})) // '[object Object]'
console.log(Object.prototype.toString.call(function(){})) // '[object Function]'
...

五.提供一个自定义检测数据类型方法

正常情况下Object.prototype.toString.call()可以满足所有的数据类型判断,但在考虑到简单类型判断使用typeof更加轻便,认为jquery中的判断封装更为巧妙
(function () {
    var classType = {}
    var toString = classType.toString; // 相当于 Object.prototype.toString

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

    var toType = function (obj) {
        // null或者undefined不再做判断直接返回
        if (obj == null) {
            return obj + ''
        }
        // 复杂类型时在classType映射表中直接获取类型,简单类型走typeof判断
        return typeof obj === "function" || typeof obj === "object" ?
            classType[toString.call(obj)] : typeof obj
    }
    // toType绑定在全局中方便调用
    window.toType = toType

})()

第一次写博客分享,肯定有很多不足之处,欢迎各位大佬指点0~0。