Js数据类型检测

一篇文章让你学会Js数据类型检测的原理及使用

前置知识:Js中的数据类型

在Js中有两大类型数据,一种是基本数据类型,一种是引用数据类型

1. 基本数据类型
类型名称
string字符串
number数字
boolean布尔值
null空对象指针
undefined未定义
symbol唯一值
bigint大整数
2. 引用数据类型
类型名称
object标准普通对象
Array、RegExp、Date、Math、Error…标准特殊对象
Number、String、Boolean…非标准特殊对象
function可调用/可执行对象(函数)

Js中的类型检测

回归正题,我们来讲讲Js中的类型检测都会用到哪些方法,以及这些方法的原理机制是怎么样的

本文列举了几个Js数据中常用的类型检测方法:

  1. typeof
  2. instanceof
  3. constructor
  4. Object.prototype.toString.call
  5. Array.isArray()
  6. isNaN

我们先说说最常用的typeof

1.typeof

typeof返回的结果是字符串,字符串中包含了对应的数据类型
来看看一些检测结果:

检测结果
typeof 1number
typeof NaN (非数字)number
typeof Infinity (无穷)number
typeof ‘’ (空字符串)string
typeof nullobject
typeof undefinedundefined
typeof symbolsymbol
typeof 10nbigint
typeof {}object
typeof []object
typeof new Numberobject
typeof function(){}function
数据类型的底层二进制表示

在讲typeof的检测机制及原理之前,我们要知道数据类型在计算机的底层都是怎么表示的

所有数据类型值,在计算机底层都是按照‘64位’的二进制进行存储的。
这里只列举数据类型二进制表示的前三位

类型二进制码前三位
对象000
字符串100
浮点数010
布尔值110
null000…(64个都是0)
undefined-2^30
typeof的检测机制:
  • typeof是按照二进制进行检测类型的。
  • 比如,二进制的前三位是0,就会被认为是对象,然后再去看有没有实现call方法,如果实现了,返回’function’,没有实现,则返回’object’。
  • null的二进制表示是64个零 而开头是000会被判定为对象,所以typeof null的结果是‘object’ ,这也是typeof的局限性

2.instanceof

检测当前实例是否属于这个类,只要当前类出现在实例的原型链上,结果都是true

  let arr=[];

  console.log(arr instanceof Array);//true

  console.log(arr instanceof RegExp);//false

  console.log(arr instanceof Object);//true

由于我们可以肆意地修改原型的指向,所以检测出来的结果可能是不准的

  function Fn(){this.x=100
  }

  Fn.prototype=Array.prototype;

  let f=new Fn;

  console.log(f,f instanceof Array);//true

不能检测基本数据类型

  console.log(1 instanceof Number);//false

附上手写版instanceof

    const instance_of=function instance_of(L,R){
        let O = R.prototype;
        L = L.__proto__;
        while (true) {
            if (L === null) {
                return false;
            }
            if (L === O) {
                return true;
            }
            L = L.__proto__
        }
    }
    let num=1;
    let arr = [];
    let obj = {
        name: '小明'
    };
    console.log(instance_of(num, String));//false
    console.log(instance_of(arr, Array));//true
    console.log(instance_of(obj, Array));//false
    console.log(instance_of(obj, Object));//true

3.constructor

对象的原型链下的一个属性:constructor
比instanceof稍微好用一点(基本类型也支持)

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

同样的问题,constructor也可以随便改,所以也不一定准确

    Number.prototype.constructor='ABC';
    let n=1;
    console.log(n.constructor===Number);//false

4.Object.prototype.toString.call(最准确)

这个是标准的检测数据类型的方法

检测结果
Object.prototype.toString.call(1)‘[object Number]’
Object.prototype.toString.call(NaN)‘[object Number]’
Object.prototype.toString.call(“”)‘[object String]’
Object.prototype.toString.call(true)‘[object Boolean]’
Object.prototype.toString.call(Symbol(‘abc’))‘[object Symbol]’
Object.prototype.toString.call({})‘[object Object]’
Object.prototype.toString.call([])‘[object Array]’
Object.prototype.toString.call(/^$/)‘[object RegExp]’
Object.prototype.toString.call(new Date())‘[object Date]’
Object.prototype.toString.call(function(){})‘[object Function]’
Object.prototype.toString.call(null)‘[object Null]’
Object.prototype.toString.call(undefined)‘[object Undefined]’

上图
在这里插入图片描述
Object.prototype.toString.call的检测原理:
Object.prototype.toString不是转换为字符串,是返回当前实例所属类的信息,结构为:’[object 所属的类]’

   let obj={
        name:'小明'
    }
    console.log(obj.toString()); //[object Object]

toString方法执行,thisobj,所以检测的结果是obj它的所属类信息
所以我们只要把Object.prototype.toString执行,让它里面的this变为要检测的值(也就是call方法),那就能返回当前所属类的信息

5.Array.isArray()

判断是否是数组

console.log(Array.isArray([]));//true
console.log(Array.isArray(new Array()));//true

6.isNaN

isNaN() 函数用于检查其参数是否是非数字值。
原理:isNaN函数接受一个参数,会先调用Number()方法尝试将参数转换为数值型,再进行判断。

    console.log(isNaN(123));//false
    console.log(isNaN('123'));//false
    console.log(isNaN(true));//false
    console.log(isNaN({}));//true
    console.log(isNaN(NaN));//true

总结

Object.prototype.toString.call是最准确最标准的,但是略麻烦,typeof只是对null和对象这些不太好用,一般都结合typeof和Object.prototype.toString.call一起使用。
真实项目当中,基本数据类型除了null以外都可以用typeof,引用数据类型里面function也可以用typeof,对象和null的话就用Object.prototype.toString.call即可。

感谢读者的耐心观看,如果觉得这篇文章对您有所帮助,麻烦点赞收藏噢😋

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值