Js数据类型检测

发布于:2023-01-14 ⋅ 阅读:(450) ⋅ 点赞:(0)

一篇文章让你学会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 1 number
typeof NaN (非数字) number
typeof Infinity (无穷) number
typeof ‘’ (空字符串) string
typeof null object
typeof undefined undefined
typeof symbol symbol
typeof 10n bigint
typeof {} object
typeof [] object
typeof new Number object
typeof function(){} function

数据类型的底层二进制表示

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

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

类型 二进制码前三位
对象 000
字符串 100
浮点数 010
布尔值 110
null 000…(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即可。

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

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到