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:2
typeof typeof [] //=>'string'
//=>typeof [] 'object'
//type of '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
猎取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;
}()