如何封装一个完整性判断数据类型的函数?

54 阅读1分钟

常规类型判断的缺点

  1. 使用typeof判断数据类型的方法
var str='小耗子';console.log(typeof str)  //string
var bool=true;console.log(typeof bool)  //boolean
var arr=[1,2,3];console.log(typeof arr) //object
var obj={a:1,b:2};console.log(typeof obj) //object

缺点:只能区分原始类型数据,无法区分object(引用类型)的数据

  1. 使用**"instanceof"**判断数据类型的方法
var obj={a:1,b:2};console.log(obj instanceof Object) //true
var obj={a:1,b:2};console.log(obj instanceof Array) //false

缺点:需要知道构造函数,即需要两个输入

  1. typeofinstanceof结合起来判断,枚举所有的类型,这并不是一个好方法,因为手动枚举是不靠谱的,不具备完整性。
// 第一,有可能忽略某些类型
// 第二,es有可能会继续增加新的类型 如Symbol Bigint

最佳方案

使用Object.prototype.toString.call()

Object.prototype.toString.call([1,2])  //"[object Array]"

注意

必须使用Object原型对象上的方法-Object.prototype.toString,不可以直接使用toString。后者可能是子类重写的
例如
[1,2].toString() //报错
这样写就相当于Array.prototype.toString.call([1,2]),所以会报错。

问题

如何实现一个getType函数,传入一个变量,能准备的获取它的类型?
// function object  array number string boolean map RegExp

实现方法

function getType(x){
         const originType=Object.prototype.toString.call(x)\
         const spaceIndex=originType.indexOf(' ')
         const type=spaceIndex.slice(spaceIndex+1,-1)
         return  type.toLowerCase()
}

测试

const map=new Map()
map.set('foo',true)
map.set('bar',false)
console.log(getType(map)) // map