前言在JavaScript中,数据类型分为两类,一类是基本数据类型,一类是复杂数据类型,也叫引用数据类型基本数据类型:NumberNumberStringStringBooleanNullUndefinedSymbolsBigInt引用数据类型:dateDete,objectObject,arrayArray,methodFunction,regularregex,collectionwithkey:Maps,Sets,WeakMaps,WeakSets基本数据类型和引用数据类型区别提到在之前的深拷贝文章中,这里不再赘述。传送门:javaScript中的深拷贝和浅拷贝简单梳理了几种常见的数据校验方式接下来我们校验以下数据类型//基本数据类型letstr="abc";letnum=123;letboo=true;letundef=undefined;lettestNull=null;letsymb=Symbol("user");letbigInt=BigInt(9007199254740999);//复杂-引用数据类型letarr=[1,2,3,4];letfunc=function(){};letobj={};letdate1=newDate();letsetObj1=newSet();letsetObj2=newSet([1,2,3]);letmapObj=新地图();typeof运算符typeof运算符将返回一个字符串,指示未计算操作数的类型/***typeofoperator**返回一个字符串,指示未计算操作数类型。***/console.log(typeofstr);//stringconsole.log(typeofnum);//numberconsole.log(typeofboo);//booleanconsole.log(typeofundef);//undefinedconsole.log(typeoftestNull);//objectconsole.log(typeofsymb);//symbolconsole.log(typeofbigInt);//bigintconsole.log(typeofObject(bigInt));//objectconsole.log(typeofarr);//objectconsole.log(typeoffunc);//functionconsole.log(typeofobj);//objectconsole.log(typeofdate1);//objectconsole.log(typeofsetObj1);//objectconsole.log(typeofsetObj2);//objectconsole.log(typeofmapObj);//对象总结在使用typeof操作符时,我们可以看到一些特殊情况:null,array数组,set,map返回对象objectinstanceofinstanceof用于检测构造函数的prototype属性是否出现在实例对象的原型链上./****instanceof**用于检测构造函数的原型属性是否出现在实例对象的原型链上。***/console.log(strinstanceofString);//falseconsole.log(newString("abc")instanceofString);//trueconsole.log(numinstanceofNumber);//falseconsole.log(newNumber(123)instanceofNumber);//trueconsole.log(booinstanceofBoolean);//falseconsole.log(newBoolean(true)instanceofBoolean);//falseconsole.log(undefinstanceofundefined);//未捕获的类型错误:'instanceof'的右侧不是对象console.log(testNullinstanceofnull);//未捕获的类型错误:'instanceof'的右侧是不是objectconsole.log(symbinstanceofSymbol);//false//Symbol不是构造函数,没有新操作符console.log(bigInstanceofBigInt);//falseconsole.log(Object(BigInt("22"))instanceofObject);//trueconsole.log(Object(BigInt("22"))instanceofBigInt);//trueconsole.log(arrinstanceofArray);//trueconsole.log(arrinstanceofObject);//trueconsole.log(funcinstanceofFunction);//trueconsole.log(funcinstanceofObj等);//trueconsole.log(objinstanceofObject);//trueconsole.log(objinstanceofFunction);//falseconsole.log(nullinstanceofObject);//falseconsole.log(date1instanceofObject);//trueconsole.log(setObj1instanceofObject);//trueconsole.log(setObj2instanceofObject);//trueconsole.log(mapObjinstanceofObject);//trueconsole.log(setObj1instanceofArray);//falseconsole.log(setObj2instanceofArray);//falseconsole.log(mapObjinstanceofArray);//falseconstructor/***constructor**返回对创建实例对象的构造函数的引用**请注意,此属性的值是对函数本身的引用,而不是包含函数名称的字符串**Constructor.prototype.constructor()***///基本数据类型letstr="abc";letnum=123;letboo=true;letundef=undefined;lettestNull=null;letsymb=Symbol("user");letbigInt=BigInt(9007199254740999);//复杂-引用数据类型letarr=[1,2,3,4];letfunc=function(){};letobj={};letdate1=newDate();functionconstructorFn(){this.name="11";}letcon1=newconstructorFn();letsetObj1=newSet();letsetObj2=newSet([1,2,3]);letmapObj=newMap();console.log(str.constructor);//Stringconsole.log(num.constructor);//Numberconsole.log(boo.constructor);//布尔值//console.log(testUndefined.constructor);//无法读取未定义的属性“constructor”//console.log(testNull.constructor);//无法读取nullconsole.log(symb.constructor)的属性“constructor”;//Symbolconsole.log(bigInt.constructor);//BigIntconsole.log(arr.constructor);//Arrayconsole.log(func.const鲁克特);//Functionconsole.log(obj.constructor);//Objectconsole.log(date1.constructor);//Dateconsole.log(constructorFn.constructor);//函数console.log(con1.constructor);//constructorFnconsole.log(setObj1.constructor);//Setconsole.log(setObj2.constructor);//Setconsole.log(mapObj.constructor);//Map/****构造函数验证***/console.log(Function.constructor);//Functionconsole.log(Object.constructor);//Functionconsole.log(Array.constructor);//Functionconsole.log(Date.constructor);//FunctionObject.prototype.toString.call&&对象。prototype.toString.applyObject.prototype.toString()在使用Object.prototype.toString.call或Object.prototype.toString.apply检查数据类型之前,我们先了解一下Object.prototype.toString中的构造函数Function和JavaScriptPrototype方法applyandcall:/***返回表示对象的字符串**Object.prototype.toString()**当对象表示为文本值时,每个对象都有一个toString()方法,或者当对象被调用时自动调用以预期的字符串方式引用*默认情况下,toString()方法由每个Object对象继承。**如果在自定义对象中未覆盖此方法,则toString()返回“[objecttype]”,其中type是对象的类型。下面的代码说明了这一点:***/letisObj={name:"zhangsan"};letisBoolean=true;letisNumber=newNumber(123);letisString="abc";letisFun=newFunction();console.log(isObj.toString());//[object对象]console.log(isBoolean.toString());//trueconsole.log(isNumber.toString());//123console.log(isString.toString());//abcconsole.log(newDate().toString());//2022年4月28日星期四16:37:19GMT+0800(中国标准时间)console.log(isFun.toString());//functionanonymous(){}call&&apply/****call()调用具有指定this值和一个或多个单独给定参数的函数,function.call(thisArg,arg1,arg2,...)**apply()使用指定的this值和一个或多个单独给定的参数来调用函数,unc.apply(thisArg,[argsArray])***///callbasicallyuses;functiona(){console.log(这);}函数b(){console.log(this);}a.call(b);//函数b(){}b.call(a);/最简单的例子/functiona(){}callandapply显示当前方法的this点被改变了。同时这两种方法的区别在于Object.prototype.toString的传参方式结合Function.prototype.call&&apply/****使用toString()检测对象类型可以通过toString()获取每个对象的类型*为了通过Object.prototype.toString()检测到每个对象,*需要使用Function.prototype.call()或者Function.prototype.apply(),将要检查的对象作为第一个参数传递,称为thisArg。**那么Object.prototype.toString就相当于原生构造函数的实例化对象isNumber,传递参数给Object.prototype.toString执行*其实相当于toString.call(new***);***/letstr=letarr=[1,2,3,4];letfunc=function(){};letobj={};letdate1=newDate();functiontestFun(){}letnewTest=newtestFun();letnewFun=newFunction();letsetObj1=newSet();letsetObj2=newSet([1,2,3]);letmapObj=newMap();console.log(Object.prototype.toString.apply(newString("sss")));//[对象字符串]console.log(Object.prototype.toString.apply(str));//[对象字符串]console.log(Object.prototype.toString.call(num));//[对象编号]console.log(Object.prototype.toString.call(boo));//[对象布尔值]console.log(Object.prototype.toString.call(undef));//[对象未定义]console.log(Object.prototype.toString.call(testNull));//[objectNull]console.log(Object.prototype.toString.call(symb));//[对象符号]console.log(Object.prototype.toString.call(Object(bigInt)));//[objectBigInt]console.log(Object.prototype.toString.call(bigInt));//[objectBigInt]console.log(Object.prototype.toString.apply(arr));//[对象数组]console.log(Object.prototype.toString.call(func));//[对象函数]console.log(Object.prototype.toString.call(obj));//[objectObject]console.log(Object.prototype.toString.call(date1));//[对象日期]console.log(Object.prototype.toString.call(testFun));//[对象函数]console.log(Object.prototype.toString.call(newTest));//[objectObject]console.log(Object.prototype.toString.call(newFun));//[对象函数]console.log(Object.prototype.toString.call(setObj1));//[对象设置]console.log(Object.prototype.toString.call(setObj2));//[对象集]console.log(Object.prototype.toString.call(mapObj));//[objectMap]其他校验数据类型的方法:判断是否为数组:console.log(Array.isArray([1,2]));//true判断一个对象是否为空对象//判断一个空对象functionisEmptyObj(obj){for(nameinobj){console.log(name);返回假;//不是空对象}returntrue;}console.log(isEmptyObj({}));//true总结一下不管是typeof操作符还是其他操作方法都有自己的缺陷。在日常的开发过程中,我们需要知道当前操作的是对象还是构造函数生成的对象或方法,这样才能针对当前需要判断的数据类型使用最合适的方法Object.prototype。.toString.call或Object.prototype.toString.apply应该是最完美的方法。当我们不确定是引用类型还是基本数据类型时,建议在了解这些判断数据类型的方法或现有问题之前先做为首选问题:使用instanceof和typeof验证时为什么数组array存在目的?这时候我们就需要了解引用数据类型的具体内容。以上判断数据类型的方法可以在项目开发过程中写入utilspublic。在这些方法中,更多的用法正在开发中,等待补充。源码地址码云https://gitee.com/lewyon/vue-notegithubhttps://github.com/akari16/vue-note文章个人博客地址:深入剖析javaScript常见数据类型检查与验证欢迎要关注公众号:程序员布欧,时不时更新一些前端介绍文章,不容易啊。转载请注明出处和作者。
