Javascript有两套数据类型,一套是基础数据类型,一套是对象数据类型。基础数据类型包括5种基本数据类型,分别是null,bool,undefined,number,string,也叫简单数据类型,object是复杂数据类型,其中Object,Array,Function属于引用类型(对象数据类型)。
基于这么多数据类型,所以JS就自带有类型判定的方法,typeof 用来检测基本数据类型,instanceof 用来检测对象数据类型,但是JS自带的这两套识别机制并不靠谱,所以产生了isXXX一系列来判断数据类型的方法,就拿typeof来说,他只能粗略的识别出string、number、boolean、function、undefined、object这6中数据类型,无法识别Null,RegExpAragument等细分对象类型
/* Javascript有两套数据类型,一套是基础数据类型,一套是对象数据类型。基础数据类型包括5种基本数据类型,分别是null,bool,undefined,number,string,也叫简单数据类型, object是复杂数据类型,其中Object,Array,Function属于引用类型(对象数据类型)。基于这么多数据类型,所以JS就自带有类型判定的方法,typeof 用来检测基本数据类型, instanceof 用来检测对象数据类型,但是JS自带的这两套识别机制并不靠谱,所以产生了isXXX一系列来判断数据类型的方法,就拿typeof来说, 他只能粗略的识别出string、number、boolean、function、undefined、object这6中数据类型,无法识别Null,RegExpAragument等细分对象类型 */ //下面就是自带的Js识别系统所带的坑 console.log(typeof null);//输出:object console.log(typeof document.childNodes);//safari 输出:function console.log(document.createElement("embed"));//ff3-10 输出:function,其他浏览器都输出object console.log(document.createElement("object"));//ff3-10 输出:function,其他浏览器都输出object console.log(document.createElement("applet"));//ff3-10 输出:function,其他浏览器都输出object console.log(typeof /d/i);//在实现了ecma262v4的浏览器上输出:function console.log(typeof window.alert);//IE678 输出:object, 其他浏览器输出:function //以上就是typeof的坑 var iframe=document.createElement("iframe"); document.body.appendChild(iframe); xArray=window.frames[window.frames.length-1].Array; var arr=new xArray(1,2,3); console.log(arr);//输出:1,2,3 console.log(arr instanceof Array);//输出:false console.log(arr.constructor===Array);//输出:false //以上是instnceof的坑,只要原型上存在此对象的构造函数,那么就返回true,但是如果跨文档比较,iframe里面的数组实例就不是父窗口里面的Array的实例 window.onload=function () { console.log(window.constructor);//IE67 undefined 其他object console.log(document.constructor);//IE67 undefined 其他object console.log(document.body.constructor);//IE67 undefined 其他object console.log((new ActiveXObject("Microsoft.XMLHttp")).constructor);//IE6789 undefined } //以上是constructor的坑,产生以上问题的原因是在旧版本IE下DOM和BOM是没有暴露出来的 console.log(isNaN("aaa"));//输出:true console.log(isNaN(new Object()));//输出:true //isNaN这个方法非常不靠谱,当我们传入字符串和对象时,输出也是true,这对我们的序列化是非常不利的 if(typeof window.ActiveXObject!="undefined") { var xhr=new ActiveXObject("Msxml2.XMLHTTP"); console.log(typeof xhr.abort);//输出:unknown } //以上是在IE下的typeof返回unknown的情况 /* 之前大多数人用document.all是否存在来判定IE,因为用document.all来取得页面中的元素是不错的注意,但是这个方法其他浏览器也觊觎了好久, 于是就有了Chrome下的闹剧 */ console.log(typeof document.all); //IE78中输出:object,在Chrome中输出:undefined console.log(document.all);//在Chrome中,虽然typeof输出的是:undefined,但是document.all却能获取到所有的网页元素,输出:HTMLAllCollection[6]
/* 以下是jQuery判断js数据类型的方法$.type */ var jQuery={}; var class2Type={}; var dataType=["Boolean","Number","String","Function","Array","Date","RegExpObject","Function"]; for(var i=0;i<dataType.length;i++) { class2Type["[object "+dataType[i]+"]"]=dataType[i].toLowerCase(); } jQuery.type=function (obj) { return obj==null?obj+"":class2Type[Object.prototype.toString.call(obj)] || "object"; } var aa=false; function bb(){} alert(Object.prototype.toString.call(aa))//输出:[object Number] alert(jQuery.type(bb))//输出:number
var mass={}; var class2Type={ "[objectHTMLDocument]":"Document", "[objectHTMLCollection]":"NodeList", "[objectStaticNodeList]":"NodeList", "[obejctIXMLDOMNodeList]":"NodeList", "[objectDOMWindow]":"Window", "null":"Null", "NaN":"NaN", "undefined":"Undefined" } var toString=class2Type.toString; var AllDataType=["Boolean","Number","String","Function","Array","Date","RegExp","Error","Symbol","Arguements","Window","Document"]; //填充class2Type集合用于判断js数据类型,通过Object.prototype.toString.call()来判断解决typeof和instanceof"不靠谱"的问题 //class2Type这个映射几乎将所有的对象类型一网打尽 for(var i=0;i<AllDataType.length;i++) { class2Type["[object "+AllDataType[i]+"]"]=AllDataType[i]; } mass.type=function (obj,str) { //1、当传入的对象不等于null或者自己的类型不等于自己的时候,直接去class2Type中找自己的类型, // 2、如果找不到做Object.prototype.toString转换,再去class2type中找 //3、如果在class2type中找不到类型,那么找传入对象的nodeName(传入的参数可能是html元素节点) //4、如果上面的条件都不满足那么就把result设为"#" var result=class2Type[(obj==null || obj!==obj?obj:toString.call(obj))] || obj.nodeName || "#"; //兼容旧版本浏览器处理个别情况,如window,opera //利用IE678中window==document为true,document==window为false的神奇特性 if(result.charAt(0)=="#") { if(obj==obj.document && obj.document!=obj) { result="Window"; } else if(obj.nodeType===9) { result="Document"; } else if(obj.callee) { result="Arguements"; } else if(isFinite(obj.length) && obj.item) { result="NodeList"; }else { result=toString.call(obj).slice(8,-1); } } if(str) { return str===result; } return result; } //type方法直接用toString.call(obj)做键,直接从事先存好的映射中取出。只有在IE6、IE7、IE8中才废一些周折处理window、document //Arguement、nodeList等模块