要检测的数据类型有 基本数据类型:Number、String、Boolean、Null、undefined 引用数据类型:Function、Array、Object、Error、JSON、RegExp(正则)
以下为创建的检测数据
函数
function fun (name,age,na,li) {
console.log(this)
}
数组
var arr = [1,2,3]
对象
var obj = {
name: 'dpn'
}
字符串
var str = 'dpn'
数字
var num = 18
null
var nul = null
布尔
var flag = true
undefined
var unde
Date
var date = new Date();
JSON
var json = {name:'wenzi', age:25};
正则
var reg = /^[a-zA-Z]{5,20}$/;
Error
var error= new Error();
1、用typeof检测
console.log(typeof(fun))//function
console.log(typeof(arr))//object
console.log(typeof(obj))//object
console.log(typeof(str))//string
console.log(typeof(num))//number
console.log(typeof(nul))//object
console.log(typeof(flag))//boolean
console.log(typeof(unde))//undefined
console.log(typeof(date))//object
console.log(typeof(json))//object
console.log(typeof(reg))//object
console.log(typeof(error))//object
只有number、string、boolean、function、undefined、object六种数据可以检测出来,其余的都是Objet
一般用来检测基本数据类型,null 会被检测为 object 是因为在浏览器底层记录数据类型的时候,null 的机器码和 object是一样的(000),所以检测 null 的时候会被当作 object 返回
2、用 instanceof 检测
console.log(str instanceof String)//false
console.log(num instanceof Number)//false
console.log(flag instanceof Boolean)//false
console.log(nul instanceof Object)//false
console.log(unde instanceof Object)//false
console.log(arr instanceof Array)//true
console.log(fun instanceof Function)//true
console.log(obj instanceof Object)//true
console.log(date instanceof Date)//true
console.log(json instanceof Object)//true
console.log(reg instanceof RegExp)//true
console.log(error instanceof Error)//true
number、string、boolea、null、undefined都是false
并且null、undefined是在检测Objec类型报false,因为他们两个没有全局类型
一般用来检测引用数据类型
原理:检测当前实例的原型链上是否存在我们要检测的数据类型
var str = new String('dpn')
var num = new Number(18)
var flag = new Boolean(true)
console.log(str instanceof String)//true
console.log(num instanceof Number)//true
console.log(flag instanceof Boolean)//true
number、string、boolean在使用创建构造函数的方式来创建变量时,检测结果是true
3、用constructor检测
在实例对象中有一个属性__proto__是指向原型对象(prototype)在原型对象中有一个属性constructor是指向的构造函数的
因为原型链是一层一层找的,所以实例对象可以直接找constructor 这个构造函数就是数据类型了
不是用new构造函数创建的变量也一样可以通过原型对象指向构造函数的
console.log(num.constructor == Number)//true
console.log(str.constructor == String)//true
console.log(flag.constructor == Boolean)//true
//console.log(nul.constructor== Object)
//console.log(unde.constructor== Object)
console.log(obj.constructor == Object)//true
console.log(arr.constructor == Array)//true
console.log(fun.constructor == Function)//true
console.log(json.constructor == Object)//true
console.log(date.constructor == Date)//true
console.log(reg.constructor == RegExp)//true
console.log(error.constructor == Error)//true
null和undefined没有构造函数
一般用来检测基本数据类型和引用数据类型 直接检测实例的构造函数来进行判断,一般会使用 == 的方式进行判断
4、使用Object.prototype.toString.call
console.log(Object.prototype.toString.call(num))//[object Number]
console.log(Object.prototype.toString.call(str))//[object String]
console.log(Object.prototype.toString.call(flag))//[object Boolean]
console.log(Object.prototype.toString.call(nul))//[object Null]
console.log(Object.prototype.toString.call(unde))//[object Undefined]
console.log(Object.prototype.toString.call(obj))//[object Object]
console.log(Object.prototype.toString.call(arr))//[object Array]
console.log(Object.prototype.toString.call(fun))//[object Function]
console.log(Object.prototype.toString.call(json))//[object Object]
console.log(Object.prototype.toString.call(date))//[object Date]
console.log(Object.prototype.toString.call(reg))//[object RegExp]
console.log(Object.prototype.toString.call(error))//[object Error]
打印结果为一个字符串,字符串里是一个数组,数组的第二个元素就是我们要的数据类型
都可以检测出来
如果要封装一个getType函数可以使用这种方法
function getType (data) {
return Object.prototype.toString.call(data).slice(8,-1)
}
通常用来检测基本数据类型和引用数据类型
原理:
首先
1、像Array、Function等数据类型都会继承Object原型上的方法,那么toString也会继承,但是他们会在原型上重写这个toString方法,那么该数据类型的实例进行继承toString方法的时候就会执行就近原则,那么就执行了该数据类型函数上重写的toString方法 【一般都是数据转换为String类型的作用,而不是我们想要的获取数据类型的作用】
2、所以如果我们要得出结果就要直接在Object.prototype上直接调用toString方法,在调用的时候使用call或者apply的方式可以让this指向该实例,那么这个实例就可以成功调用Object.prototype上面的toString方法
第二步要搞懂的就是Object.prototype上面的toString方法是怎么实现获取数据类型的呢?
ES5之前 [[class]]: 【原生对象和宿主对象】
其实,当实例在调用这个方法的时候会作一下三步:
①、把该变量先【装箱】成一个对象,【null和undefined除外,他们可以直接返回】所有的对象都拥一个内部属性 [[Class]] (一个字符串值,表明了该对象的类型),
②、获取this对象的[[Class]]属性的值
③、然后拼接在 [object, 数据类型] 数据类型的位置,我们最终所获取到的也就是这样一个数组格式的字符串
ES6中 [[NativeBrand]]【原生对象】
[[class]]内部属性,没有了,取而代之的是[[NativeBrand]]
[[NativeBrand]]: 该属性的值对应一个标志值(tag value),可以用来区分原生对象的类型 通过上述的方式进行返回一个字符串
返回的结果我们可以通过 slice(8,-1) 的方式进行获取到我们想要的数据类型