各个类型的数据类型检测
一般基本数据类型采用typeof检测null的检测会有问题,引用数据类型采用Object.prototype.toString.call(obj)来检测,首先要有一个映射表,这个映射表是一个对象,对象的属性名是Object.prototype.toString.call(xxx)的结果,对应着类型, 数据类型大体分为基本数据类型和引用数据类型,基本数据类型除了null其他都可通过typeof检测出来,null可以通过null==undefined检测并返回,引用数据类型typeof 函数返回是"function",所以只有typeof为"object"的数据要进行进一步的检测,通过对象原型上的方法toString的.call调用得到typeMap中的key从而得到对应的数据类型
//映射对象
let typeMap={}
function typeMapFunc(){
["Number","String","Boolean","Symbol","Bigint","Function","Date","RegExp","Error"].forEach(item=>{
//它的key值就是
typeMap[`[object ${item}]`]=item.toLowerCase()
})
}
typeMapFunc()
//
function toType(obj){
//首先要检测传入的值是否是null或者undefined
if(obj==null){
return obj+""
}
//如果数据不是基本数据类型或者function而是object就要通过typeMap映射表得到对应的属性值确定数据类型
return typeof obj==="object"?typeMap[Object.prototype.toString.call(obj)]:typeof obj
}
检测数据是否为function类型
function isFunction(func)
//在某些浏览器中<object>dom元素的typeof值也为function,所以在保证它的typeof值为'function'的同时,他不能是dom元素,也就是它的nodeType不能为Number类型,它不存在nodeType返回的值就是undefined,返回值就是true
typeof func==="function"&&typeof func.nodeType!=="number"
}
检测数据是否为window
function isWindow(obj){
return obj&&obj.window===window
}
检测是否是数组或类数组
检测是数组或者类数组,首先可以检测它是否为真正的数组,然后函数和window对象是由length属性的,所以要排除这两种可能,然后就是判断是否是类数组,首先要看他是否有length属性,拿到它的length,当length为0的时候或者length>0并且length-1是这个对象的属性
function isArrayLike(obj){
if(Array.isArray(obj)){
return true
}
if(isFunction(obj)||isWindow(obj)){
return false
}
let length=!!obj&&"length" in obj&&obj.length
return length===0||typeof length==="number"&&number>0&&(number-1) in obj
}
检测是否为空对象
如果对象中有属性就会进入循环,如果是私有属性就会返回false,否则就会返回true
funcion isEmptyObj(obj){
for(let key in obj){
if(!obj.hasOwnProperty(key))break
return false
}
return true
}
检测是否为纯对象
排除是null的可能并且typeof的检测结果是"object",得到它的__proto__如果为null则是纯对象,如果是Object.prototype也能证明是纯对象,于是就得到它的constructor,检验是否为Object,通过Function.prototype.toString.call(Object)的值是否相等来检测
let funcToString=Function.prototype.toString
let objectString=funcToString.call(Object)
function isPlainObject(obj){
if(!!obj||typeof obj!=="object"){
return false
}
let getProto=Object.prototype.getPrototypeOf
let objPrototype=getProto.call(obj)
if(!objPrototype){
return true
}
return objPrototype.hasOwnProperty("constructor")&&funcToString.call(objPrototype.constructor)===funcToString
}