在js中,一般使用以下几种方式进行数据类型的检测
typeof
作用:用于检测基础数据类型
底层机制:直接在计算机底层基于数据类型的值(二进制)进行检测
typeof 12
"number"
typeof "12"
"string"
typeof NaN
"number"
typeof true
"boolean"
typeof undefined
"undefined"
typeof null
"object"
typeof {}
"object"
typeof []
"object"
typeof /^$/
"object"
typeof function(){}
"function"
从上面结果可以看出来,typeof存在几个问题
- typeof null为"object",对象存储在计算机中,都是以000开始的二进制存储,null也是,所以检测出来的结果是对象
- typeof 普通对象/数组对象/正则对象/日期对象 "object"
instanceof
作用:检测当前实例是否属于这个类的 底层机制:只要当前类出现在实例的原型链上,结果都是true
缺点:
- 由于可以修改原型指向,所以检测出来的结果不准
- 无法检测基本数据类型
[] instanceof Array //true
[] instanceof RegExp //false
[] instanceof Object //true
function Fn(){
this.x=100
}
Fn.prototype=Object.create(Array.protype)
let f=new Fn
console.log(f instanceof Array) //true
console.log(1 instanceof Number)//false
constructor
作用:支持基础类型和复杂类型的检测 缺点:constructor可以修改,导致结果不准确
console.log([].constructor===Array)//true
console.log([].constructor===RegExp)//false
console.log([].constructor===Object)//false
console.log((1).constructor===Number) //true
Number.prototype.constructor='AA'
let n=1
console.log(n.constructor===Number)//false
Object.prototype.toString.call
作用:返回当前实例所属类的信息,是标准的类型检测方法,在vue源码中经常可以看到,支持检测Number、String、Boolean、Null、Undefined、Symbol、Object、Array、RegExp、Date、Function
Object.prototype.toString.call(1) //"[object Number]"
Object.prototype.toString.call("1") //"[object String]"
Object.prototype.toString.call({}) //"[object Object]"
Object.prototype.toString.call(true) //"[object Boolean]"
Object.prototype.toString.call(/^$/) //"[object RegExp]"
Object.prototype.toString.call([]) //"[object Array]"
总结:typeof、instanceof、constructor这三种方法检测类型都有其缺点,而全的检测方法是调用对象的toString方法,用法是Object.prototype.toString.call(),一般来说,在项目中封装类型检测的方法时,基本类型除了null外可以使用typeof检测,而其他的类型可以用Object.prototype.toString.call