JS数据类型判断的几种常用方法
JavaScript中常见数据类型有Number、String、Boolean、Object、Array、Json、Function、Date、RegExp、Error、undefined、Null等十几种。ES6还有新增的数据类型有Symbol、Set、Map等。在实际应用中,我们经常需要判断数据类型,现在我归纳几种方法,希望对大家有所帮助。
typeof判断(最常用)
typeof是JS提供的一个运算符,专门用来检测一个变量的类型。typeof有2种使用方式:typeof(表达式)和typeof变量名,第一种是对表达式做运算,第二种是对变量做运算。
functiondoSomething(){ console.log('HelloWorld!'); } console.log(typeof1);//number console.log(typeof'Hello');//string console.log(typeof[]);//object console.log(typeof{});//object console.log(typeofdoSomething);//function console.log(typeoftrue);//boolean console.log(typeofnewDate());//object console.log(typeofnewRegExp());//object console.log(typeofJSON.stringify({ name:'zhencanhua' }));//string console.log(typeofnull);//object console.log(typeofundefined);//undefined console.log(typeof(newError('error!')));//object console.log(typeofa);//undefined console.log(typeofSymbol());//symbol console.log(typeofnewSet());//object console.log(typeofnewMap());//object
从上面打印结果可以看出,typeof不能区分引用型数据的类型和null。另我们可以使用Array.isArray(arr)将数组类型的数据从中筛选出来。
instanceof判断(了解)
instanceof用来检测构造函数的prototype属性是否出现在某个实例对象的原型链上。语法:object(实例对象)instanceofconstructor(构造函数)。是的话返回true,否则返回false。所以,instanceof运算符只能用作对象的判断。针对typeof不能判断的引用型数据,我们可以使用instanceof运算符。
letarr1=[1,2,3]; letobj1={ name:'小明' }; functionPersion(){} letpersion1=newPersion(); console.log(arr1instanceofArray);//true console.log(arr1instanceofObject);//true,Array是Object的子类 console.log(obj1instanceofObject);//true console.log(obj1instanceofArray);//false console.log(PersioninstanceofFunction,PersioninstanceofObject);//truetrue console.log(nullinstanceofObject);//false console.log(persion1instanceofPersion,persion1instanceofFunction,persion1instanceofObject);//truefalsetrue //String对象和Date对象都属于Object类型 letstr1='Hello'; letstr2=newString(); letstr3=newString('你好'); letmyDate=newDate(); console.log(str1instanceofString,str1instanceofObject);//false,false console.log(str2instanceofString,str2instanceofObject);//true,true console.log(str3instanceofString,str3instanceofObject);//true,true console.log(myDateinstanceofDate,myDateinstanceofObject);//true,true
从上面的判断可以看出,instanceof的使用限制很多,而且还不能很清晰方便的判断出一个实例是数组还是对象或方法。
针对上面方法的弊端,我们可以使用Object.prototype上的原生toString()方法来检测数据的类型。
Object.prototype.toString.call()判断(最靠谱)
Object是JS提供的原生对象,Object.prototype.toString对任何变量都会返回这样一个字符串"[objectclass]",class就是JS内置对象的构造函数的名字。call是用来改变调用函数作用域的。
Object.prototype.toString()在toString方法被调用时执行下面的操作步骤:
- 获取this对象的[[Class]]属性的值。(所以使用call来改变this的指向)
- 将字符串"[object",第一步获取的值,以及"]"拼接成新的字符串并返回。
[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性。在规范中,[[Class]]是这么定义的:内部属性的描述,[[Class]]是一个字符串值,表明了该对象的类型。
读了上面的说明,用call的关键地方就在第1步,获取的是this对象,不加call改变作用域时this指向的是Object.prototype。
functiondoSomething(){ console.log('HelloWorld!'); } //使用Object.prototype.toString.call来判断 console.log(Object.prototype.toString.call(1));//[objectNumber] console.log(Object.prototype.toString.call('Hello'));//[objectString] console.log(Object.prototype.toString.call(false));//[objectBoolean] console.log(Object.prototype.toString.call({}));//[objectObject] console.log(Object.prototype.toString.call([1,2,3]));//[objectArray] console.log(Object.prototype.toString.call(newError('error!')));//[objectError] console.log(Object.prototype.toString.call(newDate()));//[objectDate] console.log(Object.prototype.toString.call(newRegExp()));//[objectRegExp] console.log(Object.prototype.toString.call(doSomething));//[objectFunction] console.log(Object.prototype.toString.call(null));//[objectNull] console.log(Object.prototype.toString.call(undefined));//[objectUndefined] console.log(Object.prototype.toString.call(JSON.stringify({ name:'zhencanhau' })));//[objectString] console.log(Object.prototype.toString.call(Math));//[objectMath] console.log(Object.prototype.toString.call(Symbol('abc')));//[objectSymbol] console.log(Object.prototype.toString.call(newSet()));//[objectSet] console.log(Object.prototype.toString.call(newMap()));//[objectMap]
但在实际应用时我们只想获取返回的结果中数组的第二项,比如"[objectNumber]",我们只想要Number这段字符,那么我们可以写个函数进行过滤:
//通过定义一个公共函数获取数据类型 functiongetTypeName(val){ letstr=Object.prototype.toString.call(val); return/^\[object(.*)\]$/.exec(str)[1]; } console.log(getTypeName(false));//Boolean console.log(getTypeName());//Undefined console.log(getTypeName(null));//Null
上面的问题完美解决。
constructor判断(比较常用)
每一个对象实例都可以通过constrcutor对象来访问它的构造函数。JS中内置了一些构造函数:Object、Array、Function、Date、RegExp、String等。我们可以通过数据的constrcutor是否与其构造函数相等来判断数据的类型。
vararr=[]; varobj={}; vardate=newDate(); varnum=110; varstr='Hello'; vargetName=function(){}; varsym=Symbol(); varset=newSet(); varmap=newMap(); arr.constructor===Array;//true obj.constructor===Object;//true date.constructor===Date;//true str.constructor===String;//true getName.constructor===Function;//true sym.constructor===Symbol;//true set.constructor===Set;//true map.constructor===Map//true
但是这种方式仍然有个弊端,就是constructor所指向的的构造函数是可以被修改的。
functionName(name){ this.name=name; } functionStuent(age){ this.age=age; } //将构造函数Name的实例赋给Student的原型,Student的原型的构造函数会发生改变,将不再指向自身。 Stuent.prototype=newName('张三'); Stuent.prototype.constructor===Name;//true Stuent.prototype.constructor===Stuent;//false
以上就是我在项目中用到过的数据类型的判断方法,具体使用哪一种,还需要根据自己的实际需求来判断选择。
到此这篇关于JS数据类型判断的几种常用方法的文章就介绍到这了,更多相关JS数据类型判断内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!