1

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

Francis
122 声望5 粉丝