当前位置: 首页 > 后端技术 > Node.js

前端知识合集2

时间:2023-04-03 13:17:24 Node.js

前端学习节选,持续更新中...1.数组去重的三种解决方案①使用set去重:set是ES6中提供的一种数据结构,不同于数组,所有的值不重复,Set内部使用===判断是否相等,类似'1'和1会同时存两个,NaN和NaN只会存一个letunique=[...newSet([1,'1',1,NaN,NaN,undefined,undefined,null,null])];//[1,"1",NaN,undefined,null]②遍历,将值添加到新数组中,使用indexOf()来判断该值是否存在,如果已经存在则不添加,从而达到去重的效果。(NaN去重失败)leta=[1,'1',1,NaN,NaN,undefined,undefined,null,null];让unique=arr=>{让newA=[];arr.forEach(key=>{if(newA.indexOf(key)<0){//遍历newA中是否有key,如果有大于0的key则跳过push步骤newA.push(key);}});返回新A;}唯一(一);//["1",1,NaN,NaN,undefined,null]③遍历,将数组的值加到一个对象的属性名上,给属性赋值。对象不能添加相同的属性名,基于此,可以对数组进行去重,然后使用Object.keys(object)返回这个对象的可枚举属性组成的数组。该数组是去重数组。(返回的字符串都是1,'1'都为'1')leta=[1,'1',1,NaN,NaN,undefined,undefined,null,null];letunique=arr=>{varobj={};arr.forEach(value=>{obj[value]=0;//随机赋值,为了给obj对象添加属性});返回Object.keys(obj);}unique(a);//["1","NaN","undefined","null"]2.深拷贝深度遍历属性值拷贝函数deepcopy(obj){varcopyObj=Object.create(Object.getPrototypeOf(obj));Object.getOwnPropertyNames(obj).forEach((keyName)=>{if(typeofobj[keyName]=='object'){copyObj[keyName]=deepcopy(obj[keyName])}else{copyObj[keyName]=obj[键名]}});returncopyObj;}使用JSON.parse(JSON.stringify(obj)),有限制functiondeepcopy(obj){returnJSON.parse(JSON.stringify(obj));}3.函数长度属性functionlength的含义attribute:函数期望传入的参数个数,指定默认值后,length不指定默认值会返回参数个数;指定默认值后,长度属性将被扭曲。(function(a){}).length//1(function(a=5){}).length//0(function(a,b,c=5){}).length//2如果设置了默认值的参数不是尾参数,所以长度属性不再包含在后面的参数中。(function(a=0,b,c){}).length//0(function(a,b=1,c){}).length//14.参数作用域如果参数默认值为变量,那么该变量的作用域就和其他变量的作用域规则一样,即先是当前函数的作用域,再是全局作用域。varx=1;functionf(x,y=x){console.log(y);}f(2)//2在上面的代码中,参数y的默认值等于x。调用时,因为已经生成了函数作用域内的变量x,所以y等于参数x,而不是全局变量x;如果调用时没有生成函数作用域内的变量x,则结果不同。让x=1;函数f(y=x){让x=2;console.log(y);}f()//1上面代码中,调用函数时,y的默认值变量x还没有在函数内部生成,所以x指向全局变量。如果此时全局变量x不存在,会报错:ReferenceError:xisnotdefined复杂的例子:varx=1;functionfoo(x,y=function(){x=2;}){变量x=3;y();console.log(x);}foo()//3上面代码中,函数foo的参数y的默认值为匿名函数。调用函数foo时,其参数x的值是undefined,所以y函数内部的x一开始是undefined,然后重新赋值给2。函数foo重新声明了一个x,值为3。这两个x不同,互不影响,所以最后输出3。如果去掉varx=3的var,这两个x是一样的,最后输出的是2。5、call方法实现继承的简单使用(同apply)调用:obj1.method.call(obj2,argument1,argument2,...),将当前对象obj1替换为对象obj2,如果obj2为空,它是一个全局对象。简单使用:functionadd(a,b){returna+b;}functionsub(a,b){返回a-b;}add.call(sub,3,1);//4继承:functionParent(){this.showMsg=function(msg){returnmsg;}}functionChild(){Parent.call(this);//this.super()表示}constchi=newChild();chi.showMsg('你好世界');//'helloworld'多重继承:functionParent1(){this.add=function(a,b){returna+b;}}functionParent2(){this.sub=function(a,b){returna-b;}}functionChild(){Parent1.call(this);Parent2.call(this);}6.Javascript词法作用域JavaScript是词法作用域而不是动态作用域,词法作用域是写代码的,也就是说在定义的时候就确定了,而动态作用域是在运行时确定的。词法作用域关注函数的声明位置,动态作用域关注函数的调用位置。但是,在JS中this也与函数调用有关。函数foo(){console.log(a);//2}functionbar(){vara=3;foo();}vara=2;bar()如果按照动态作用域理论进行运算,结果为:37。展平数组[0,[1,[2,[3,[4]]]]]=>[0,1,2,3,4]toString():constflatten=(arr)=>arr。toString().split(',')reduce():functionflatten(arr){returnarr.reduce((acc,val)=>{returnacc.concat(Array.isArray(val)?flatten(val):val)},[]);};