JavaScript中的一些实用小技巧总结
前言
这篇文章主要记录一下平时自己实践得到的,博客中学习的以及在一些项目源码中看到的javascript技巧。有些东西可以说是奇淫技巧,有些可能是ES6+中一些比较具有实用性的新语法。
&&和||的妙用
有时候我们需要在某个函数或变量为true时执行另外一个函数。例如:
consttask1=()=>{ console.log('执行task1'); returnMath.random()>=0.5; } consttask2=()=>console.log('task1执行成功后执行task2'); if(task1())task2();
上面的if语句可以使用&&直接简写为:
task1()&&task2();
如果还要在task1失败(也就是task1返回false)后执行task3,可以使用:
consttask3=()=>console.log('task1执行失败后执行task3'); task1()&&task2()||task3();
本质上还是利用了&&和||的短路特性。
其实这里使用条件运算符也是可以的:
task1()?task2():task3();
下面展示一个我最近使用reacthooks开发的项目的的一个代码片段:
constProfileItem=(props)=>{ const{name,value,render}=props; return({name} {/*根据是否有render这个props来返回不同的内容*/} {render&&render(props)|| }
函数默认值
ES5版本
使用短路或操作符来设置函数默认值的方式其实很常见。但是有一些坑,下面展示的代码中当默认值参数为一个数字时,传参为0还是会使用默认值,必须对y为0的时候单独进行判断。
constpow=(x,y)=>{ y=y||2; letresult=1; for(leti=0,max=y;i4 console.log(pow(2,3));//=>8 //当y传值为0时,y取值2 console.log(pow(2,0));//=>4
ES6版本
ES6在语法层面提供的默认值语法就靠谱的多了
constpow=(x,y=2)=>{ letresult=1; for(leti=0,max=y;i4 console.log(pow(2,3))//=>8 console.log(pow(2,0));//=>1
类数组转数组
类数组指的是像arguments,jquery对象一样可以使用下标访问还有length属性的和数组很像但并不是数组的一类对象。
类数组没有slice,map等集合函数,这也是为什么我们有时候需要将类数组转换成数组的原因。
functionfunc(){ for(leti=0,max=arguments.length;ifalse //类数组没有slice,forEach,map等集合函数 console.log(arguments.slice===undefined);//=>true } func('Google','facebook','Microsoft'); //=> //Google //facebook //Microsoft
ES5中的转换方法
将Array原型中的slice方法绑定到arguments对象上调用,并且不传参数目的为了让其返回所有的元素。
functionfunc(){ constarray=Array.prototype.slice.call(arguments); console.log(array.slice(0,1)); } func('Google','facebook','Microsoft');//=>['Google']
ES6中的转换方法
ES6将类数组转换成数组的方法多一些。
使用扩展运算符
functionfunc(){ console.log([...arguments]) } func('Google','facebook','Microsoft');//['Google','facebook','Microsoft']
使用Array.from
functionfunc(){ console.log(Array.from(arguments)) } func('Google','facebook','Microsoft');//['Google','facebook','Microsoft']
构造一个连续整数的数组
这里就直接给出我觉得最好的方法了
//输出2开始连续的8个整数 constarray=Array.from({length:8}).map((ele,index)=>index+2); console.log(array);//=>[2,3,4,5,6,7,8,9] //评论区指出有更简洁的版本,Array.from自带的映射函数 constarray=Array.from({length:8},(ele,index)=>index+2); console.log(array);//=>[2,3,4,5,6,7,8,9]
函数参数使用解构赋值
函数参数比较多的时候我们往往会让参数直接接受一个配置对象。但是使用对象参数我们无法设置默认值,在函数体中使用对象参数时还需要使用通过对象参数来访问,当访问次数比较多或者嵌套比较深就会觉得不方便。在函数参数中使用解构赋值就解决了上面的问题。
//必须给对象参数设置默认值,不然传参数时因为没有解构对象会报错 constgetUsers=({ offset=0, limit=1, orderBy="salary" }={})=>{ //根据条件查询数据库返回用户数据 console.log({offset,limit,orderBy}); } getUsers({offset:10,limit:20,orderBy:'age'});//=>{offset:10,limit:20,orderBy:'age'} getUsers();//=>{offset:0,limit:1,orderBy:'salary'}
使用!!将其它类型转换成bool型
console.log(!!{});//true console.log(!!0);//false console.log(!![]);//true console.log(!!undefined);//false consthttpGet=(url,retry)=>{ if(!!retry){ //超时重发 } }
JSON.stringify
深度克隆
使用先序列化再反序列化这种方式来深度克隆对象在一般情况下很方便,缺点就是无法克隆函数以及继承的属性。
如果还要克隆函数属性,推荐使用lodash的cloneDeep。
constme={ name:'lyreal666', age:23, speak(){ console.log(`Hello,I'mly!`); } } constclonedMe=JSON.parse(JSON.stringify(me)); console.log(clonedMe);//=>{name:'lyreal666',age:23} console.log(clonedMe.speak===undefined);//=>true
使用第二个和第三参数
JSON.stringify的第二个参数是用来对属性值进行处理的,第三个参数则是用来指定输出的json字符串的缩进长度,可以传数字也可以传字符串。
constme={ name:'lyreal666', age:23, speak(){ console.log(`Hello,I'mly!`); } } constjsonStr=JSON.stringify(me,(key,value)=>key==='name'?'老余':value,2); console.log(jsonStr); /*=> { "name":"老余", "age":23 } */
优雅的遍历对像
使用解构赋值和Object.entries。
constme={ name:'lyreal666', age:23, speak(){ console.log(`Hello,I'mly!`); } } for(const[key,value]ofObject.entries(me)){ console.log(`${key}:${value}`); } /*=> name:lyreal666 age:23 speak:speak(){ console.log(`Hello,I'mly!`); } */
清空数组的最快方法
评论区有人说这种直接修改length的做法是有问题的,我之前也看过关于清空数组的方法的讨论,但是我觉得一般情况下这样用是没什么问题的,既简单,又不用重新分配内存给新数组。
constarray=[1,2,3,4]; array.length=0; console.log(array);//=>[] //网友指出可以更好的方式是直接赋值空数组 letarray=[1,2,3,4]; array=[];
判断一个整数是否是-1
//~操作符的运算规律可以简单记作将加一的结果取反 console.log(~1);//=>-2 console.log(~0);//=>-1 console.log(~(-3));//=>2 console.log(~(-1));//=>0 constnumber=-2; //判断一个数是否为-1 if(!~number){ //当number是-1的操作... }
立即执行函数
立即执行函数可以让我们的代码中的变量不污染外部变量,常见的使用方式是像下面这样的。
//使用括号将函数括起来调用 (function(window,$){ //内部代码 })(window,jQuery)
更优雅的方式是下面这种,事实上很多其它的算术运算符比如+,-,*,~等也是可以的。
!function(window,$){ //内部代码 }(window,jQuery) //还可以使用+,-,*等 +function(window,$){ //内部代码 }(window,jQuery) //更神奇的是还可以用new,typeof等操作符 newfunction(window,$){ //内部代码 }(window,jQuery);
使用set来对数组去重复
console.log([...newSet([1,3,1,2,2,1])]);//=>[1,3,2]
使用reduce连乘或连加
constarray=[1,2,3,4]; //连加 console.log(array.reduce((p,c)=>p+c));//=>10 //连乘 console.log(array.reduce((p,c)=>p*c));//=>24
取整
Math中的一堆取整函数这里就不说了,主要是提一些比较巧妙地取整方式。
console.log(~~3.14);//=>3 console.log(~~(-2.5));//=>-2 console.log(6.18|0);//=>6 console.log(-3.6|0);//=>-3 console.log(9.9>>0);//=>9 console.log(-2.1>>0);//=>-2 //superagent是一个很实用的发送http请求的node模块,它对返回码的处理就用到了| vartype=status/100|0; //status/class res.status=status; res.statusType=type; //basics res.info=1==type; res.ok=2==type; res.clientError=4==type; res.serverError=5==type; res.error=4==type||5==type;
使用+将其它类型转换成number类型
console.log(+'3.14');//=>3.14 console.log(typeof+'3.14')//=>number constsleep=(milliseconds)=>{ returnnewPromise((resolve,reject)=>{ setTimeout(()=>resolve(),milliseconds); }); } //当然这里可以考虑使用console.time来测试 !asyncfunctionmain(){ conststart=+newDate(); awaitsleep(3000); constend=+newDate(); console.log(`执行了${end-start}`);//执行了3002 }();
使用科学计数法表示大数字
conststr1='hello'; conststr2='world' console.time('测试+拼接字符串'); for(leti=0;i<200000000;i++){ constjoinedStr=str1+str2; } console.timeEnd('测试+拼接字符串'); console.time('测试模板字符串拼接字符串'); //使用科学计数法比打8个0方便不少 for(leti=0;i<2E8;i++){ constjoinedStr=`${str1}${str2}`; } console.timeEnd('测试模板字符串拼接字符串') /*=> 测试+拼接字符串:3238.037ms 测试模板字符串拼接字符串:3680.225ms */
交换变量值
直接利用解构赋值
leta=666; letb=999; [a,b]=[b,a]; console.log({a,b});//=>{a:999,b:666}
获取随机字符串
截取下标2开始后的字符串是因为不需要Math.random()返回的小数构成的字符串的0.这两个字符。使用36进制可以制造字符种类更多些的随机字符串
console.log(Math.random().toString(16).substring(2));//13位=>45d9d0bb10b31 console.log(Math.random().toString(36).substring(2));//11位=>zwcx1yewjvj
扁平化数组
ES2019新增了Array.prototype.flat,目前chrome最新正式版73.0.3683.103已经支持了,node最新的LTS10.15.3还不支持,node最新开发版11.13.0是支持的。这里贴一个在掘金一个兄弟面经里面看到的比较hack的方法,这里要注意根据情况做类型转换。
constarray=[1,[2,[3,4],5],6,7]; console.log(array.toString().split(',').map(ele=>Number.parseInt(ele)));//=>[1,2,3,4,5,6,7]
最近面试腾讯,阿里前端实习岗真的是一言难尽,后面打算整篇文章聊聊我最近的面试经历。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。