当前位置: 首页 > Web前端 > JavaScript

js数据类型、闭包

时间:2023-03-26 23:41:43 JavaScript

js有哪些数据类型和区别基本数据类型string/number/boolean/undefined/null/symbol(表示创建后唯一且不可变的数据类型)reference数据类型object基本数据类型的区别引用数据类型声明变量时存储分配不同。基本数据类型存放在栈中,引用数据类型存放在堆中。不同的内存分配机制导致不同的访问机制。基本类型可以直接访问,引用数据要先访问栈中存放的引用地址,然后根据引用地址在堆中找到实体。(不能直接访问堆内存的位置,直接操作堆内存空间,只能操作栈内存中对象的引用地址)给变量赋值时,基本数据类型会赋值一份将原值的值传递给新变量(传值),而引用类型是将引用类型的地址复制到新变量(传地址)应该有值,但实际上缺少*转换为数值不一样,把null转成数值类型就是0,undefined转成数值类型变成NAN*null表示“没有对象”,这里不应该有值null和undefined的使用场景*null1.作为一个parameterofafunction,表示函数的参数不是对象2.作为对象原型链的终点(Object.getPrototypeOf(Object.prototype)valueisnull)*undefined1.声明变量但是没有赋值2.调用的时候fu使用了nction,没有提供应该提供的参数,参数等于undefined3.对象没有属性赋值,属性的值是undefined4.函数没有返回值时,默认返回undefinedconsole.log(Number(null))console.log(Number(undefined))console.log(Object.getPrototypeOf(Object.prototype))JS数据类型检测方法*typeof(检测数据类型的运算符)*typeofnull结果是Object本质上是一个bug。在javascript的初始版本中,使用的是32位系统,js使用低位存储变量类型信息,用于性能优化。判断数据类型时,根据机器码的低位标识进行判断,null的机器码标识全为0,对象的机器码低位标识为000。所以typeofnull的结果被误判为Objectconsole.log('value',typeof7)//valuenumberconsole.log('string',typeof'77')//stringstringconsole.log('Booleanvalue',typeoftrue)//布尔值booleanconsole.log('array',typeof[])//数组对象console.log('function',typeoffunction(){})//functionfunctionconsole.log('object',typeof{})//objectobjectconsole.log('undefined',typeofundefined)//undefinedundefinedconsole.log('null',typeofnull)//nullobject*instanceof(检查一个实例是否属于这个class)*能正确判断对象的类型,但不能判断基本数据类型*内部运行机制:判断是否能在其原型链上找到该类型的原型*注意:不能用于检测null,undefinedtypeconsole.log('Number',7instanceofNumber)//Numberfalseconsole.log('String','77'instanceofString)//Stringfalseconsole.log('Boolean',trueinstanceofBoolean)//Booleanfalseconsole.log('array',[]instanceofArray)//arraytrueconsole.log('function',function(){}instanceofFunction)//functiontrueconsole.log('object',{}instanceofObject)//objecttrue*构造函数(检测关系在实例和类之间,从而检测数据类型,并引用最初构造对象的函数)console.log('value',(7).constructor===Number)//值为真console.log('string',('77').constructor===String)//stringtrueconsole.log('booleanvalue',(true).constructor===Boolean)//Booleantrueconsole.log('array',([]).constructor===Array)//arraytrueconsole.log('function',(function(){}).constructor===Function)//Functiontrueconsole.log('object',({}).constructor===Object)//Objecttrue*Object.prototype.toString.call()*为什么在原型上使用toString方法:因为数据是从Object实例创建,但是会重写数据本身的toString方法,通过调用复制原型上的方法可以准确判断数据类型。朋友们,强烈推荐这个方法!consttypeOfStr=str=>Object.prototype.toString.call(str).slice(8,-1)console.log('number',typeOfStr(7))//Number数字console.log('string',typeOfStr("77"))//StringStringconsole.log('Boolean',typeOfStr(true))//BooleanBooleanconsole.log('Array',[],typeOfStr([]))//数组Arrayconsole.log('function',typeOfStr(function(){}))//函数函数console.log('object',typeOfStr({}))//对象对象console.log('undefined',typeOfStr(undefined))//undefined未定义的缺点ole.log('null',typeOfStr(null))//null空闭包定义:1.函数中返回一个函数,2.函数声明的作用域与函数使用的作用域不同目的:获取privatescopeVariables(这里的timer是私有作用域变量,这些变量可以保存在内存中)constdebounce=(()=>{lettimer=null;return(callback,time)=>{timer&&clearTimeout(timer)timer=setTimeout(callback,ti??me)}})()闭包的优缺点优点:避免全局变量污染变量长期保存在内存中(缓存变量)缺点:内存泄漏(消耗),常驻内存,增加内存占用面试真题//正常方式varfnArr=[];for(vari=0;i<10;i++){fnArr[i]=function(){returni}}console.log(i)//结果是10控制台。log(fnArr[7]())//结果是10//闭包写法varfnArr=[];for(vari=0;i<10;i++){fnArr[i]=(function(){letj=i;returnfunction(){returnj}})()}console.log(i)//结果为10console.log(fnArr[7]())//结果为7