常规类型判断的缺点
- 使用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(引用类型)的数据
- 使用**"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
缺点:需要知道构造函数,即需要两个输入
- typeof和instanceof结合起来判断,枚举所有的类型,这并不是一个好方法,因为手动枚举是不靠谱的,不具备完整性。
// 第一,有可能忽略某些类型
// 第二,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