JS中的数据类型检测专题汇总

作者:日期:2017-11-23 16:51:41 点击:141

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;
}();

上一篇: 正则表达式从基础到深入实战

下一篇: JS中的变量提升、作用域、闭包核心原理解读