JS中检测数据类型的方案

一、检测数据类型1:typeof
返回结果都是字符串
字符串中包含了对应的数据类型:“number”/“string”/“boolean”/“undefined”/“symbol”/“object”/“function”
【局限性】
typeof null = “object”, null是空对象指针(在代码中会提现用法)
检测数组或者正则等特殊的对象,返回结果都是"object",所以无法基于typeof判断是数据还是正则

<script>
        let obj = {}; //=> obj的值等于一个堆内存,称为AAAFFF000,若这个堆内存在其他位置被占用,不能销毁,但是若想销毁的时候就直接给obj赋值为null,让obj不再指向任何堆内存,obj=null,在浏览器空闲的时候,就会销毁这个没有被占用的堆内存(谷歌浏览器就是随时检测在空闲的时候看哪些堆内存没有被占用,就会释放这个堆内存;IE浏览器不同,堆内存被一个变量占用计数为1,被两个变量占用计数为2,若把其中一个赋值为null,计数直接减1)
        console.log(12); //number
        console.log(typeof []); //=> "object"
        console.log(typeof typeof []); //=>“string” 无论前面多少typeof,返回结果都是"string"
    </script>

二 / 三、检测数据类型2/3:instanceof/constructor
检测某个实例是否属于这个类
它检测的底层机制:所有出现在其原型链上的类,检测结果都是TRUE,
【局限性】:
由于可以基于__proto__或者prototype改动原型链的动向,所以基于instanceof检测出来的结果并不一定是准确的。
基本数据类型的值,连对象都不是,更没有__proto__。虽说也是所属类的实例,在JS中也可以调取所属类原型上的方法,但是instanceof是不认得

<script>
        // console.log(12 instanceof Number); //=>false
        // console.log(new Number(12) instanceof Number); //=>true
        // console.log([] instanceof Array); //=>true
        // console.log([] instanceof Object); //=>true

        function Fn() { };
        Fn.prototype.__proto__ = Array.prototype;
        let f = new Fn();
        //原型链:f -> Fn.prototype -> Array.prototype -> Object.prototype
        console.log(f instanceof Array); //true,f不是数组,不满足数组的结构,因上面一行的作用,可以调用数组原型上的方法,因为原型链指向可以随意改动,所以instanceof出来的结果不一定是准确的。 
        let arr = [];
        Array.prototype.constructor = null;
        // console.log(arr.constructor === Array); false ,与instanceof一样,constructor是可以随意修改的,当prototype改变时,constructor也会改变,值是不准确的
        //基本数据类型也可以用constructor判断
        console.log(arr.constructor); //null
        console.log((12).constructor === Number); //true

四、检测数据类型4:Object.prototype.toString.call([value])/({}).toString.call([value])
不是用来转换为字符串的,而是返回当前实例所属类的信息
格式:"[object 所属类的信息]"
“[object Object/Array/RegExp/Date/Function/Null/Undefined/Number/String/Boolean/Symbol…]”
这种方式基本上没有什么局限性,是检测数据类型最准确的方式

<script>
        //可以直接f12在控制台中输入Number/String/Boolean/Symbol/Array等.prototype查看他们的原型,会显示如以下信息
        /*
        Number.prototype
        Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, …}constructor: ƒ Number()toExponential: ƒ toExponential()toFixed: ƒ toFixed()toPrecision: ƒ toPrecision()toString: ƒ toString()valueOf: ƒ valueOf()toLocaleString: ƒ toLocaleString()__proto__: Object[[PrimitiveValue]]: 0
        String.prototype
        String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …}length: 0constructor: ƒ String()anchor: ƒ anchor()big: ƒ big()blink: ƒ blink()bold: ƒ bold()charAt: ƒ charAt()charCodeAt: ƒ charCodeAt()codePointAt: ƒ codePointAt()concat: ƒ concat()endsWith: ƒ endsWith()fontcolor: ƒ fontcolor()fontsize: ƒ fontsize()fixed: ƒ fixed()includes: ƒ includes()indexOf: ƒ indexOf()italics: ƒ italics()lastIndexOf: ƒ lastIndexOf()link: ƒ link()localeCompare: ƒ localeCompare()match: ƒ match()matchAll: ƒ matchAll()normalize: ƒ normalize()padEnd: ƒ padEnd()padStart: ƒ padStart()repeat: ƒ repeat()replace: ƒ replace()search: ƒ search()slice: ƒ slice()small: ƒ small()split: ƒ split()strike: ƒ strike()sub: ƒ sub()substr: ƒ substr()substring: ƒ substring()sup: ƒ sup()startsWith: ƒ startsWith()toString: ƒ toString()trim: ƒ trim()trimStart: ƒ trimStart()trimLeft: ƒ trimStart()trimEnd: ƒ trimEnd()trimRight: ƒ trimEnd()toLocaleLowerCase: ƒ toLocaleLowerCase()toLocaleUpperCase: ƒ toLocaleUpperCase()toLowerCase: ƒ toLowerCase()toUpperCase: ƒ toUpperCase()valueOf: ƒ valueOf()Symbol(Symbol.iterator): ƒ [Symbol.iterator]()__proto__: Object[[PrimitiveValue]]: ""
        Boolean.prototype
        Boolean {false, constructor: ƒ, toString: ƒ, valueOf: ƒ}constructor: ƒ Boolean()toString: ƒ toString()valueOf: ƒ valueOf()__proto__: Object[[PrimitiveValue]]: false
        Symbol.prototype
        Symbol {Symbol(Symbol.toStringTag): "Symbol", constructor: ƒ, toString: ƒ, valueOf: ƒ, …}description: (...)constructor: ƒ Symbol()toString: ƒ toString()valueOf: ƒ valueOf()Symbol(Symbol.toStringTag): "Symbol"Symbol(Symbol.toPrimitive): ƒ [Symbol.toPrimitive]()get description: ƒ description()__proto__: Object
        Function.prototype
        ƒ () { [native code] }
        dir(Function.prototype)
        VM688:1 ƒ anonymous()arguments: (...)caller: (...)length: 0name: ""constructor: ƒ Function()apply: ƒ apply()bind: ƒ bind()call: ƒ call()toString: ƒ toString()Symbol(Symbol.hasInstance): ƒ [Symbol.hasInstance]()get arguments: ƒ ()set arguments: ƒ ()get caller: ƒ ()set caller: ƒ ()__proto__: Object[[FunctionLocation]]: <unknown>[[Scopes]]: Scopes[0]
        Array.prototype
        [constructor: ƒ, concat: ƒ, copyWithin: ƒ, fill: ƒ, find: ƒ, …]length: 0constructor: ƒ Array()concat: ƒ concat()copyWithin: ƒ copyWithin()fill: ƒ fill()find: ƒ find()findIndex: ƒ findIndex()lastIndexOf: ƒ lastIndexOf()pop: ƒ pop()push: ƒ push()reverse: ƒ reverse()shift: ƒ shift()unshift: ƒ unshift()slice: ƒ slice()sort: ƒ sort()splice: ƒ splice()includes: ƒ includes()indexOf: ƒ indexOf()join: ƒ join()keys: ƒ keys()entries: ƒ entries()values: ƒ values()forEach: ƒ forEach()filter: ƒ filter()flat: ƒ flat()flatMap: ƒ flatMap()map: ƒ map()every: ƒ every()some: ƒ some()reduce: ƒ reduce()reduceRight: ƒ reduceRight()toLocaleString: ƒ toLocaleString()toString: ƒ toString()Symbol(Symbol.iterator): ƒ values()Symbol(Symbol.unscopables): {copyWithin: true, entries: true, fill: true, find: true, findIndex: true, …}__proto__: Object
        RegExp.prototype
        {constructor: ƒ, exec: ƒ, …}dotAll: (...)flags: (...)global: (...)ignoreCase: (...)multiline: (...)source: (...)sticky: (...)unicode: (...)constructor: ƒ RegExp()exec: ƒ exec()compile: ƒ compile()toString: ƒ toString()test: ƒ test()Symbol(Symbol.match): ƒ [Symbol.match]()Symbol(Symbol.matchAll): ƒ [Symbol.matchAll]()Symbol(Symbol.replace): ƒ [Symbol.replace]()Symbol(Symbol.search): ƒ [Symbol.search]()Symbol(Symbol.split): ƒ [Symbol.split]()get dotAll: ƒ dotAll()get flags: ƒ flags()get global: ƒ global()get ignoreCase: ƒ ignoreCase()get multiline: ƒ multiline()get source: ƒ source()get sticky: ƒ sticky()get unicode: ƒ unicode()__proto__: Object
        */
        //Number/String/Boolean/symbol 他们的原型上都有:
        //  =>toString:转化为字符串
        //  =>valueOf:返回原始值(都是基本类型的值)
        //Array/RegExp/Function等内置类的原型上都有:
        //  =>toString:转化为字符串
        // Object的原型上:
        //  =>toString:返回当前实例所属类的信息
        //  =>valueOf:返回原始值(都是基本类型的值)

        //  Object.prototype.toString.call([]); //容易理解的写法
        // let obj = {}; obj.toString(); //=>结果"[object Object]" 不直接写Object.prototype.toString也可以,但是调用的依旧是Object原型上的toString方法 
        // ({}).toString(); //=>"[object Object]" 也可以直接这么写,简便易懂的写法
        /*
         具体使用,可以直接在控制台中输入:
            ({}).toString.call(12)  => "[object Number]"
            ({}).toString.call('12')  => "[object String]"
            ({}).toString.call(true)  => "[object Boolean]"
            ({}).toString.call(null)  => "[object Null]"
            ({}).toString.call(undefined)  => "[object Undefined]"
            ({}).toString.call(Symbol())  => "[object Symbol]"
            ({}).toString.call([])  => "[object Array]"
            ({}).toString.call(/^$/)  => "[object RegExp]"
            ({}).toString.call(function(){})  => "[object Function]"
        */
        // 也可以直接控制台输出,以检验这种方法是否可行
        console.log(({}).toString.call(12)); //[object Number]
        console.log(({}).toString.call([])); //[object Array]
        console.log(({}).toString.call(Symbol())); //[object Symbol]
        console.log(({}).toString.call(/^$/)); //[object RegExp]
    </script>

以上就是四种检测数据类型的方法,总结:
对于基本数据类型,一般都是使用typeof就可以搞定,比较简单
而对于引用类型的,比如想检测是否是数组,若不严谨的情况下instanceof就可以,若要严谨就要使用Object.prototype.toString.call([要检测的值])

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值