js判断数据类型的方法(亲测最全)

前言

在开发过程中,这种需要判断数据类型的操作还是常见的,特别是一些公共组件里的数据处理方法,又或者对一些功能函数,比如递归深拷贝,需要对不同的数据做出判断.

在js中,数据分为基础类型和引用类型.比如字符串,数字等就属于基础类型,对象数组等属于引用类型.

共有五种方法,都是本人亲测.而这几种方法,有完美的,有不完美的,下面一一测试

数据准备

这里准备了很多类型或者同类型各种形式出现的数据

        let argumentFun = function(a,b,c){
            return arguments
        }
        class Myclass{
            constructor(params) {
                this.value = 1
            }
        }
    let arr = [
                '我是一个字符串',  //字符串
        9999,  //number
        true, //boolean
        {name:'王惊涛'},  //存储对象
        ['1','2','3'],  //数组
        NaN,  //NaN
        null, //null
        undefined, //安迪范的
        new Object(), //object
        Symbol(10), //symbol
        BigInt(999999999),  //bigInt
        function(){console.log('普通函数')},  //普通函数
        ()=>{console.log('箭头函数')}, //箭头函数
        argumentFun(), //类数组
        Myclass, //类
        window, //全局的window
        new Date(), //时间类型,
        Math,  //Math
        /^\w+$/ //正则
    ]

typeof方法

代码


    console.log('typeof方法---------------')
    typeofFun(arr)


        function typeofFun(value){
          arr.forEach(item=>{
            console.log(item,':',typeof item)
          })
        }

结果

结论

typeof能有效区分基础类型的变量,但是对于引用类型和特殊一些的数据则无法区分,所以用来判断数组,布尔,字符串和安迪范的就好

 instanceof方法

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。(MDN上的原定义)

语法为 object instanceof constructor

即为 : (实例对象) instanceof (构造函数)

代码

    let str1 = '1'
    let str2 = new String('1')
    let udfd1 = undefined
    let udfd2 = new Object(undefined)
    let nan1 = NaN
    let nan2 = new Number(NaN)
    let obj1 = {
        name:'wjt'
    }
    let obj2 = new Object({
        name:'wjt'
    })
    let arr1 = [1,2,3]
    let arr2 = new Array(1,2,3)
    let reg1 = /^\w+$/
    let reg2 = new RegExp(/^\w+$/)

    let fun1 = function(a,b){
        return arguments
    }
    let fun2 = new Function((a,b)=>{
        return arguments
    })
            /** instanceof方法测试 */
    console.log(str1 instanceof String,'基础类型定义','str1')  //false
    console.log(str2 instanceof String,'包装类型定义','str2')  //true


    console.log(udfd1 instanceof Object,'基础类型定义','udfd1')  //false
    console.log(udfd2 instanceof Object,'包装类型定义','udfd2')  //true


    console.log(nan1 instanceof Number,'基础类型定义','nan1')  //false
    console.log(nan2 instanceof Number,'包装类型定义','nan2')  //true

    console.log(obj1 instanceof Object,'字面量定义','obj1')  //true
    console.log(obj2 instanceof Object,'new构造定义','obj2')  //true

    console.log(arr1 instanceof Array,'字面量定义','arr1')
    console.log(arr2 instanceof Array,'new构造定义','arr2')

    console.log(reg1 instanceof RegExp,'字面量定义','reg1')  //true
    console.log(reg2 instanceof RegExp,'new构造定义','reg2')  //true

    console.log(fun1 instanceof Function,'字面量定义','fun1')  //true
    console.log(fun2 instanceof Function,'new构造定义','fun2')  //true

    console.log(fun1() instanceof Object,'字面量定义','fun1()') //true
    console.log(fun2() instanceof Object,'new构造定义','fun2()') //true

结果

扫描二维码关注公众号,回复: 16604926 查看本文章

 结论

直接定义的基础类型不可以使用instanceof判断,引用类型或者包装之后的基础类型可以

constructor方法

代码

    let str1 = '1'
    let str2 = new String('1')
    let udfd1 = undefined
    let udfd2 = new Object(undefined)
    let nan1 = NaN
    let nan2 = new Number(NaN)
    let obj1 = {
        name:'wjt'
    }
    let obj2 = new Object({
        name:'wjt'
    })
    let arr1 = [1,2,3]
    let arr2 = new Array(1,2,3)
    let reg1 = /^\w+$/
    let reg2 = new RegExp(/^\w+$/)

    let fun1 = function(a,b){
        return arguments
    }
    let fun2 = new Function((a,b)=>{
        return arguments
    })

    /** constructor方法 */
    console.log(str1.constructor,'str1')
    console.log(str2.constructor,'str2')
    // console.log(udfd1.constructor,'udfd1')  error
    console.log(udfd2.constructor,'udfd2')
    console.log(nan1.constructor,'nan1')
    console.log(nan2.constructor,'nan2')
    console.log(obj1.constructor,'obj1')
    console.log(obj2.constructor,'obj2')
    console.log(reg1.constructor,'obj1')
    console.log(reg2.constructor,'obj2')
    
    //下面的全为true
    console.log(str1.constructor === String)
    console.log(udfd2.constructor === Object)
    console.log(nan1.constructor === Number)
    console.log(obj1.constructor === Object)
    console.log(reg1.constructor === RegExp)
    console.log(arr1.constructor === Array)
    console.log(fun1().constructor === Object)
    // console.log(fun2().constructor,'========')  error

结果

 结论

可以查询数据的属性,但是特殊情况下会有报错

is类型的api

Object.prototype.toString.call方法

代码

        let argumentFun = function(a,b,c){
            return arguments
        }
        class Myclass{
            constructor(params) {
                this.value = 1
            }
        }
    let arr = [
        '我是一个字符串',  //字符串
        9999,  //number
        true, //boolean
        {name:'王惊涛'},  //存储对象
        ['1','2','3'],  //数组
        NaN,  //NaN
        null, //null
        undefined, //安迪范的
        new Object(), //object
        Symbol(10), //symbol
        BigInt(999999999),  //bigInt
        function(){console.log('普通函数')},  //普通函数
        ()=>{console.log('箭头函数')}, //箭头函数
        argumentFun(), //类数组
        Myclass, //类
        window, //全局的window
        new Date(), //时间类型,
        Math,  //Math
        /^\w+$/ //正则
    ]

    /** toString.call()方法 */
    tocall(arr)
    function tocall(value){
        arr.forEach(item=>{
            //好几种写法,一个意思
            // console.log(item,':',toString.call(item))
            // console.log(item,':',Object.prototype.toString.call(item)) 
            // console.log(item,':',Object.prototype.toString.apply(item)) 
            console.log(item,':',Object.prototype.toString.bind(item)()) 
        })
    }
   

结果

 结论

[object ???]的结果,各种类型都区分的很明白,最完美的一个方法.

并且语法好几个,都可以

总结

为了代码的安全和健壮,果断选最后一个吧.

Object.prototype.toString.call( ??? ) 或者 toString.call( ??? )

猜你喜欢

转载自blog.csdn.net/m0_54741495/article/details/132453652