typeof用来检测数据类型的运算符语法:typeof[value]typeof 12 //=>’number’typeof NaN //=>’number’typeof ‘’=>‘string’var flag=true;typeof flag //‘boolen’tpeof undefined //=>‘undefined’function fn(n,m){ if(typeof n===‘undefined’){ }}typeof null //=>‘object’ //虽然是基本数据类型值,但是它属于空对象指针,检测的结果是对象typeof {} //=>‘object’ typeof function(){} //=>‘function’typeof [] //=>‘object’typeof /^$/ //=>‘object’//使用typeof有自己的局限性,不能具体细分当前的值是数组还是正则(也就是不能细分对象类型的值)typeof (1>1?0:2) //=>’number’typeof 1>1?0:2 //=>先算typeof 1-> ’number’=> ’number’>1?0:2typeof typeof [] //=>‘string’//=>typeof [] ‘object’ //type of ‘object’ =>‘string’instanceof & constructorinstanceof : 检测某一个实例是否属于某各类的实例constructor : 构造函数 使用instanceof 检测某个值是否属于某一个数据类型的内置类,从而检测出它是否是这个类型的值;使用instanceof可以实现typeof实现不了的,对对象类型值详细的区分检测;[] instanceof Array //=>true[] instanceof RegExp //=>false使用instanceof检测也有自己的弊端:1.基本类型值无法基于它的检测var num =12;num.toFixed(2) =>‘12.00’ //12是Number类的一个实例,可以调取Number.prototype上的方法,但是它是基本类型值var num2=new Number(12);num2.toFixed(2) =>‘12.00’ typeof num //=>’number’typeof num2//=>‘object’//不管是哪一种方式创建基本类型值,都是自己所属类的实例(只不过类型不一样而已)num instanceof Number //=>falsenum2 instanceof Number //=>true2.instanceof 检测的原理是基于原型链检测的:只要当前类在实例的原型链上,最后返回的结果都是true.var ary=[];ary instanceof Array //=>trueary instanceof Object //=>truefunction Fn(){}Fn.prototype=new Array();//=>原型继承(Fn 是Array的子类)var f=new Fn();f instanceof Array //=>true 但是f其实不是数组,虽然在它的原型上可以找到数组,但是它不具备数组的基础结构,这也是instanceof的弊端constructor获取当前检测数据值的constructor,判断它是否是某一个数据类型内置类来检测var ary=[];ary.constructor===Array //=>trueary.constructor===RegExp //=>falseary.constructor===Object //=>falseary.constructor=‘AA’ary.constructor===Array; //false//=>constructor检测数据类型非常不可靠,因为这个属性是经常容易被修改的。Object.prototype.toString.call获取Object.prototype上的toString方法,让方法中的this变为需要检测的数据类型值,并且让方法执行在Number、String、Boolean、Array、Function、RexExp…这些类的原型上都有一个toString方法:这个方法就是将自身的值转换为字符串的(12).toString() //=>‘12’(true).toString() //=>’true’[12,23].toString() //=>‘12,23’…在Object这个类的原型上也有一个方法toString,但是这个方法并不是把值转换为字符串,而是返回当前值的所属类详细信息[object 所属的类]var obj={name:’tom’}obj.toString() //=>"[object Object]" 调取的是Object.prototype.toString /obj.toString() 首先执行Object.prototype.toString 方法 这个方法的this就是我们操作的数据值obj* =>总结:Object.prototype.toString执行的时候会返回当前方法中的this的所属类信息** 也就是,我们想知道谁是所属类信息,我们就把这个toString方法执行,并且让this变为我们检测的这个数据值,那么方法返回的结果就是当前检测这个值的所属类信息* Object.prototype.toString.call([value])* ({}).toString.call([value])* */Object.prototype.toString.call(12) //=>’[object Number]‘Object.prototype.toString.call(true) //=>’[object Boolean]‘Object.prototype.toString.call(’’) //=>’[object String]‘Object.prototype.toString.call({}) //=>’[object Object]‘Object.prototype.toString.call(null) //=>’[object Null]‘Object.prototype.toString.call([]) //=>’[object Array]‘Object.prototype.toString.call(/^$/) //=>’[object RegExp]‘Object.prototype.toString.call(function(){}) //=>’[object Function]‘使用toString检测数据类型,不管你是什么类型值,都可以正常检测出需要的结果(这个方法检测是万能的)alert({name:’tom’}) //[object Object] alert()=>转换为字符串弹出 //如果弹对象字符串 alert(JSON.stringify({name:’tom’}))检测数据类型方法封装~function(){ let obj={ isNumber:‘Number’, isString:‘String’, isBoolean:‘Boolean’, isNull:‘Null’, isUndefined:‘Undefined’, isPlanObject:‘Object’, isArray:‘Array’, isRegExp:‘RegExp’, isFunction:‘Function’ } let check={}; for (let key in obj) { if (obj.hasOwnProperty(key)) { check[key]=(function(classValue){ return function(val){ return new RegExp(’\[object ‘+classValue+’\]’).test(Object.prototype.toString.call(val)) } })(obj[key]) } } window.check=check;}()