typeof
用来检测数据类型的运算符
语法:typeof [value]
返回结果:首先是一个字符串,字符串中包含了我们需要检测的数据类型
typeof 12 =>'number'typeof NaN =>'number'typeof '' =>'string' var flag=true;typeof flag =>'boolean' typeof undefined =>'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; =>2 //=>先计算typeof 1->'number' =>'number'>1?0:2 typeof typeof [] =>'string'//=>typeof [] =>'object'//=>typeof 'object' =>'string'
instanceof & constructor
instanceof :检测某一个实例是否隶属于某个类
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 =>true
2、instanceof检测的原理是基于原型链检测的:只要当前类在实例的原型链上,最后返回的结果都是true
var ary=[];ary instanceof Array =>trueary instanceof Object =>true function 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 =>false ary.constructor='AA';ary.constructor===Array =>false //=>constructor检测数据类型非常不可靠,因为这个属性是经常容易被修改的
Object.prototype.toString.call([value])
获取Object.prototype上的toString方法,让方法中的this变为需要检测的数据类型值,并且让方法执行
在Number、String、Boolean、Array、Function、RegExp…这些类的原型上都有一个toString方法:这个方法就是把本身的值转换为字符串的
(12).toString() =>'12'(true).toString() =>'true'[12,23].toString() =>'12,23'...
在Object这个类的原型上也有一个方法toString,但是这个方法并不是把值转换为字符串,而是
返回当前值的所属类详细信息,固定结构:'[object 所属的类]'
var obj={name:'珠峰'};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 Number]""[object Boolean]""[object String]""[object Null]""[object Undefined]""[object Object]""[object Array]""[object RegExp]""[object Function]"...
使用toString检测数据类型,不管你是啥值,我们都可以正常检测出需要的结果(这个方法检测是万能的)
检测数据类型方法的封装
~function () {var obj = {isNumber: 'Number',isString: 'String',isBoolean: 'Boolean',isNull: 'Null',isUndefined: 'Undefined',isPlanObject: 'Object',isArray: 'Array',isRegExp: 'RegExp',isFunction: 'Function'};var check = {};for (var 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;}();