如何检测JavaScript的各种类型
一、先介绍下5种原始类型
JavaScript中5种原始类型为string,number,boolean,undefined,null
varname="Jack"; varage=32; varsingle=false; varapp;//undefined console.log(typeofname);//string console.log(typeofage);//number console.log(typeofsingle);//boolean console.log(typeofapp);//undefined console.log(typeofnull);//object
发现除null外的其他4种基本类型均可以用typeof来识别:
if(typeofname==="string"){name+="Zhang";} if(typeofage==="number"){age++;} if(typeofsingle==="boolean"&&single){…} if(typeofapp==="undefined"){app={};}
因为typeofnull会得到object,所以直接用===来检测null:
if(el===null){…}
二、对象
JavaScript的对象包括内置对象(Date,RegExp,Error等)和自定义对象。
(注意,Function和Array虽然也都是内置对象,但下一节单独讲)
对象不能像基本类型那样用typeof来检测了,因为检测出来的结果都是object:
console.log(typeofnewDate());//object console.log(typeofnewRegExp());//object console.log(typeofnewError());//object console.log(typeofnewPerson());//用typeof检测出自定义对象也是object
要改用instanceof来检测:
vardate=newDate(); varreg=newRegExp(); varerr=newError(); varme=newPerson(); if(dateinstanceofDate){//检测日期 year=date.getFullYear(); } if(reginstanceofRegExp){//检测正则表达式 reg.test(...); } if(errinstanceofError){//检测异常 throwerr; } if(meinstanceofPerson){//检测自定义对象 ... }
但自定义对象有个问题,假设浏览器frameA里和frameB里都定义了Person。frameA里定义了me对象,用meinstanceofPerson检测出来为true。但当自定义对象me传给frameB后,在frameB里instanceof会是false。
本节一开头就说了,Function和Array虽然也都是内置对象,但留到下一节讲。原因就是Function和Array也有和自定义对象相同的上述问题。因此Function和Array一般不用instanceof
三、Function
上面说了用instanceof检测Function不能跨frame。因此用typeof来检测,它可跨frame:
varfunc=function(){}; if(typeoffunc==='function'){…}
但IE8以前用typeof来检测DOM系函数会得到object,因此IE8以前改用in:
console.log(typeofdocument.getElementById);//object,不是function console.log(typeofdocument.getElementsByTagName);//object,不是function console.log(typeofdocument.createElement);//object,不是function //IE8以前的IE浏览器,要改用in来检测是否支持DOM函数 if("getElementById"indocument){…} if("getElementsByTagName"indocument){…} if("createElement"indocument){…}
四、Array
上面说了用instanceof检测Array不能跨frame。ES5之前都自定义检测方法。其中最精确的方法:依赖Array的toString会返回固定字符串”[ObjectArray]”的事实来检测:
functionisArray(arr){ returnObject.prototype.toString.call(arr)==="[ObjectArray]"; }
该方法精确且优雅,因此被很多库所采纳,最终在ES5被作为isArray方法引入了Array,参照MDN。现在你不需要自定义检测方法了,直接用isArray()即可。
其他检测方法,都各有缺陷,不能100%精确。但作为一种思路是可以借鉴的。例如依赖Array是唯一包含sort方法的对象的事实来检测:
functionisArray(arr){ returntypeofarr.sort==="function"; }
如果是自定义对象也定义了sort方法,该方法就失效了。
五、属性
检测属性是否在实例对象中应该用hasOwnProperty。如果你不关心属性是在实例对象中还是在原型对象中,可以简单点用in
例如检测字面量对象属性:
varPerson={ name:"Jack", age:33 }; if("name"inPerson){…}//true if(Person.hasOwnProperty("name")){…}//true
例如实例对象属性:
varPerson=function(name,age){ this.name=name; this.age=age; }; Person.prototype.location="Shanghai"; varme=newPerson("Jack",33) if("name"inme){…}//true if(me.hasOwnProperty("name")){…}//true if("location"inme){…}//true if(me.hasOwnProperty("location")){…}//false
除此之外其他方法都不好:
if(object[propName])//NotGood,你怎么知道属性值不是0或1? if(object[propName]===null)//NotGood,你怎么知道属性值不是null? if(object[propName]===undefined)//NotGood,你怎么知道属性值不是undefined?
总结
用typeof检测string,number,boolean,undefined,Function
用===检测null
用isArray()检测Array
用instanceof检测内置对象(除Function和Array)和自定义对象
用hasOwnProperty检测属性是否在实例对象中。如果你不关心属性是在实例对象中还是在原型对象中,可以简单点用in
好了,本篇介绍如何检测JavaScript各种类型的内容就到这里了,希望大家能够认真学习本文的内容,或许对大家学习JavaScript有所帮助。