JS中的数据类型检测
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 =>false
num2 instanceof Number =>true
2、instanceof检测的原理是基于原型链检测的:只要当前类在实例的原型链上,最后返回的结果都是true
var ary=[];
ary instanceof Array =>true
ary 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 =>true
ary.constructor===RegExp =>false
ary.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;
}();
网友评论