前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Js检测数据类型

Js检测数据类型

作者头像
Snine
发布2022-02-11 09:06:34
3K0
发布2022-02-11 09:06:34
举报
文章被收录于专栏:前端开发笔录

typeof()

代码语言:javascript
复制
/** 基本数据类型 */
let a = 99                // 理论:number        结果:number      有效
let str = '这是字符串'      // 理论:string        结果:string      有效
let und= undefined        // 理论:undefined     结果:undefined   有效
let blean = true          // 理论:boolean       结果:boolean     有效
let sym = Symbol()        // 理论:Symbol        结果:symbol      有效
let nul = null             // 理论:null         结果:object      无效
/** ES10新增Bigint类型 */
var int = Bigint(100);
typeof int = bigint;            // 理论:bigint         结果:bigint     有效

/** 引用数据类型 */
let obj = {a:1,b:2}       // 理论:object      结果:object        无效
function fn() {}          // 理论:function    结果:理论:function 无效
let arr = [1,2,3]         // 理论:array       结果:object        无效

总结

  • 对于基本数据类型, 除了null其他都会返回正常的结果
  • 对于引用数据类型,除了function其他都会返回object
  • 对于null,会返回object,历史遗留问题,也是bug,原因在于JS初始版本使用的是32位系统,为了性能考虑使用低位存储变量的类型信息,而000开头代表的是对象,null表示全零,所以对象的类型被误判为object.虽然现在的内部类型判断代码已经改变了,但是对于这个Bug缺一直流传下来了
  • 对于function会返回function

null拥有自己的Null类型,而引用数据类型中,例如数组、日期、正则、等都有自己的类型,但是typeof返回了其原型链顶端的Objec类型,不能算错误,但是不准确,不是我们想要的值

instanceof

instanceof是用来检测A是不是B的实例,表达式是A instance B,返回的是boolean,instanceof检测的是原型,所以他的检测方式是,查看A的prototype是否出现在B的__proto__ 上,也可以理解为A的是否是B的实例。

代码语言:javascript
复制
/** 基本数据类型 number string undefined boolean Symbol bull */
let a = 99                // 理论:false        结果:false       错误
let str = '这是字符串'      // 理论:false        结果:false       错误
let und= undefined        // 理论:报错          结果:报错         错误
let blean = true          // 理论:false        结果:false       错误
let sym = Symbol()        // 理论:false        结果:symbol      错误
let nul = null             // 理论:报错         结果:报错         错误

/** 引用数据类型 array function object */
let obj = {a:1,b:2}       // 理论:true       结果:true       正确
function fn() {}          // 理论:true       结果:true       正确
let arr = [1,2,3]         // 理论:true       结果:true       正确

总结

  • 通过打印可以发现,instanceof对于基本数据类型全部返回false,所以是错误的,单纯的定义一个字面量是无法通过instanceof进行检测的,如果我们要对其检测,需要通过new方式,就可以了。 let str = new String('我是字符串') console.log(str instanceof String) //true
  • 检测引用数据的类型全部正确,所以一般来讲这个方法我们是用于检测引用数据类型的。

原理

代码语言:javascript
复制
console.log([] instanceof Object) //true

例如上面这个检测过程 我们可以理解为

[].prototype => Array.prototype => Object.prototype

数组的原型会指向Array.prototype,间接的指向了Object.prototype,所以[]也属于对象返回正确,所以说instanceof判断的是两个对象是否属于实例关系,而不会直接返回数据类型,也就不能准确的判断出数据属于哪种类型。

Object.prototype.toString.call()
代码语言:javascript
复制
/** 基本数据类型 number string undefined boolean Symbol bull */
let a = 99                // 理论:number        结果:Number      正确
let str = '这是字符串'      // 理论:string        结果:String      正确
let und= undefined        // 理论:undefined     结果:Undefined   正确
let blean = true          // 理论:boolean       结果:Boolean     正确
let sym = Symbol()        // 理论:Symbol        结果:Symbol      正确
let nul = null             // 理论:null         结果:Null        正确
let int = Bigint(99)       // 理论:bigint       结果:bigint        正确

/** 引用数据类型 array function object */
let obj = {a:1,b:2}       // 理论:object      结果:Object       正确
function fn() {}          // 理论:function    结果:Function     正确
let arr = [1,2,3]         // 理论:array       结果:Array        正确

可以看出通过Object.prototype.toString.call(xx)的检测结果对于这些基础数据类型都是正确的,一般来讲,在常用的检测数据类型中,这种事最为准备的方法,那么是如何实现呢

原理

首先我们看看传统的toString()方法和Object原型上的toString()有何区别

代码语言:javascript
复制
var arr = [1,2,3]
console.log(Object.prototype.toString.call(arr)) //[object Array]
console.log(arr.toString()) // 1,2,3

可以看出传统的toString()是吧arr转换成字符串了,并不能够检测类型,所以看完这个大家应该明白,直接Object.prototype上面的toString才可以检测数据类型。这里也涉及到原型链的知识,我们分析一下:

首先arr.toString调用的是Array.prototype上面的toSting(),虽然Array也继承与Object但是这个方法在Array上进行了重写,所以两个toString也是不一样的,所以当我们 .toString.call(arr)的时候就调用的是Object的原型上面的toString,所以可以判断出对象类型

注意

  • {}调用传统的toString()返回的不是{},是*[object Object]* var strb = {} console.log(strb.toString()) // [object Object]
  • 原始类型为什么可以调用呢? var num = 123; /** .toString();—系统内部经过包装类包装–>new Number(num).toString(); */ /** 包装类: new Number(); new String(); new Boolean() */ 原始类型在调用前都会经过new去包装成类,所以就可以用过原型去找到toString。
  • 包装类也是对象,既然都是对象为什么调用toString()返回结果不一样? 我们知道继承可以拿到object原型上的toString的方法,可以判断数据类型,但是并不能满足我们的其他需求,所以作为子类的包装类就重写了toString方法,所以当我们调用时就会调用自身重写的方法,直接我们通过call指向Object原型的时候才可以去正在的判断类型。
  • 需要注意的是 检测类型的返回值并不是直接可以使用 是这种格式的[object Array],需要自己进行处理,后面的就是我们的格式

封装

日常开发中,最为准确的就是第三中方法,所以,这里我们来封装一个检测数据类型的方法:

代码语言:javascript
复制
var tsType = function (data){
    var s = Object.prototype.toString.call(data);
    return s.match(/\[object (.*?)\]/)[1].toLowerCase();
  };
  • 基本数据类型目前有 number、string、undefined、null、boolean、Symbol、Bigint、七种类型
  • 引用数据类型泛指 object,object包含了多种数据类型,例如,Function、Array、RegExp、Date、Map、Set类型等等
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • typeof()
    • 总结
    • instanceof
      • 总结
        • 原理
          • Object.prototype.toString.call()
        • 原理
          • 注意
          • 封装
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档