文章目录
👉 前言
在前端开发中,无论是否使用框架,在代码编写上,都与
Javascript
息息相关。更何况是在 框架(基于 Js 搭建的框架) 盛行的当下,以 Vue框架为例。
Vue
有着使 HTML和JS直接关联的方法,也就是
Vue指令
。比如:
v-if、v-for、v-bind、v-model
等等,其中都多少和
Javascript
相关联,并且有些指令,甚至能够使 Javascript代码直接穿插在 HTML中。
所以学习 Javascript 就显得尤为重要了,接下来,小温将给大家带来,Javascript 相关的一些知识点及小技巧!
提示:以下是本篇文章正文内容,下面案例可供参考
👉 学习目的 及 版本
> 学习目的:
- 减少
LOC
(代码行数)的数量,提高代码质量; - 降低代码时间/空间复杂度;
- 灵活使用
Javascript
中小技巧,降低开发所需时间; - 适用于
编程比赛
、黑客马拉松
、限时任务
,使代码看起来更加简洁高效; - 当然是为了征服 Javascript 啦 🤣
> 版本
本文中,大多数
JavaScript Hacks
使用
ECMAScript6 (ES2015/ES6)
以后的技术,尽管最新版本是
ECMAScript11(ES2020)
。
接下来,废话不多说,进入正题!
👉 Javascript 技巧
正文阶段:内容中所有 案例代码均在 Google Chrome 的控制台 进行过测试,运行无误! 放心 “ 食用 ”
⌨️ 1、声明和初始化数组
使用 数组对象 Array自带的填充函数 fill(每个项填充的内容) 来填充数组。
> 语法
const array =Array( integer ).fill(itemVal);/*
integer 为所要声明的数组长度
itemVal 为声明的数组每项的初始值
可以配合 数组遍历函数 map 来声明 N维数组
语法如下:
*/const array =Array( integer_1 ).fill(itemVal_1).map(item=>{// 可以添加一些需要逻辑处理的操作returnArray( integer_2 ).fill(itemVal_2)});
> 执行案例
💡 Tips:建议上手试试喔,几行代码。好记性不如烂笔头,多动手,记得牢!
⌨️ 2、数组求和、求最值(最大 / 最小)、扁平化多维数组
使用 数组对象 Array自带的函数 reduce(),接收一个函数作为累加器,进行逻辑判断,处理数据中的项。
> 语法
array.reduce((pre, cur, index, arr)=>{...}, init);
- pre: 必需。初始值(
当设定了初始化时,返回为初始值
), 或者计算结束后的返回值(sum
)。 - cur: 必需。当前元素。
- index: 可选。当前元素的索引。
- arr: 可选。当前元素所属的数组对象。
- init: 可选。传递给函数的初始值,相当于pre的初始值。
注意:reduce里面有一定要return,return出去的值也要注意。
具体使用 👉 点击跳转 大佬文章,讲解内容偏多,只讲常用的,讲复杂了,大家也不好吸收 😁。
> 执行案例
案例一:数组求和
const total = arr.reduce((sum, item)=>{return sum + item
},0);
案例二:数组求最值 - 最大 / 最小
// 求数组中的最大值 arr[max]const max = arr.reduce((a, b)=> a > b ? a : b );// 求数组中的最小值 arr[min]const min = arr.reduce((a, b)=> a < b ? a : b );
案例三:数组扁平化多维数组
const total = arr.reduce((newArr, itemArr)=>{return newArr.concat(itemArr)},[]);
> 执行效果
💡 Tips:建议上手试试喔,几行代码。好记性不如烂笔头,多动手,记得牢!
⌨️ 3、对字符串、数字或对象数组进行排序
JavaScript中数组排序的方法有两个reverse()和sort()。
- reverse()方法会反转数组项的顺序。
- sort()方法会按照字符串升序排列数组项。
注意:
sort()
方法会调用每个数组项的tostring()方法,即使数组中的每一项都是数值,
sort()
方法比较的也是字符串。
所以为了弥补
sort()
无法比较数值的缺陷,允许接收一个比较函数作为参数。
比较函数接收由原数组
依次
循环传递连续的两个数组
项作为比较函数的两个参数。规则如下:
- 如果第一个参数应该位于第二个参数
之前
,返回一个负数,相当于返回值为false
时,不调换
它们的位置。 - 如果两个参数相等,则返回
0
,0
也相当于false
。不调换
它们的位置。 - 如果第一个参数应该位于第二个参数之后,返回一个正数,正数为一个
true
值,调换
它们的位置。
具体理解,可以看下面的案例,可以配合案例理解规则
> 实际案例
① 排序字符串数组
const stringArr =["Joe","Kapil","Steve","Musk"]// 按照字符串比较, 字符串对应的编码值
stringArr.sort();// 输出(4)["Joe","Kapil","Musk","Steve"]// 此处是以 sort 转换过的值,再倒序
stringArr.reverse();// 输出(4)["Steve","Musk","Kapil","Joe"]
② 排序数字数组
const array =[40,100,1,5,25,10];// 这里匹配到了最开头讲述的 sort 接受比较函数的处理规则// ----升序----
array.sort((a,b)=> a-b);// 等价于 a - b > 0, 详细解释往下看
array.sort((a,b)=> a > b);// 输出(6)[1,5,10,25,40,100]// ----降序----
array.sort((a,b)=> b-a);// 等价于
array.sort((a,b)=> b > a);// 输出(6)[100,40,25,10,5,1]
③ 对象数组排序
原理其实都差不多,根据
sort
接受比较函数,函数的返回值来确定,是否调换位置,返回值会被当成一个布尔值来判断,控制是否调换。
比如, 上文中的 “
a - b
”, 如果循环中,
a - b > 0
,使用不等式转换一下,为
a > b
, 即 判断 a是否大于b , 若大于,则为
true
。为
true
,则调换位置,反之,为
false
则不变。
sort函数相当于 自动执行了 设定 判断规则的
冒泡排序
,循环对数组中两个连续的项进行设定规则校验。
const objectArr =[{first_name:'Lazslo',last_name:'Jamf'},{first_name:'Pig',last_name:'Bodine'},{first_name:'Pirate',last_name:'Prentice'}];
objectArr.sort((a, b)=> a.last_name.localeCompare(b.last_name));// 输出(3)[{…},{…},{…}]0:{first_name:"Pig",last_name:"Bodine"}1:{first_name:"Lazslo",last_name:"Jamf"}2:{first_name:"Pirate",last_name:"Prentice"}length:3
💡 Tips:建议上手试试喔,几行代码。好记性不如烂笔头,多动手,记得牢!
⌨️ 4、从数组中过滤出虚假值
使用 数组对象 Array自带的函数
filter()
,函数返回一个新数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
同时,该函数接收一个参数,参数可以是方法,但方法必须返回布尔值。若返回
true
,则将对应的数组项返回到新数组中,
false
,则不返回!
> 语法
const newArr = array.filter((currentValue, index, arr)=>{...}, thisVal);
function
:整体必须传一个函数,或者其他替代值currentValue
: 必需。当前元素的值。index
: 可选。当前元素的索引。arr
: 可选。当前元素所属的数组对象。thisVal
: 可选。该对象作为执行回调时使用,传递给函数,作为 “ this ”的值。如果省略 “thisVal
”,this
值为undefined
。
❗ 注意
filter()
不会对空数组进行检测;filter()
不会改变原始数组。
具体使用方法,可以跳转到我之前 《Js 技巧 数组篇》,在此不多做赘述!
接下来看特殊栗子 🌰 – 去除数组中的虚假值
> 执行案例
const array =[3,0,6,7,'',false];
array.filter(Boolean);// 等价于
array.filter(item=> item);// 将会判断 数组中的每一项,是否在转变为布尔值的时候,为 true,从而起到去除虚假值的效果// 输出(3)[3,6,7]
由于比较简单,就不做效果图展示啦,大伙动动手, 自己测试下吧!
⌨️ 5、灵活运用 Javascript 中的逻辑运算符
逻辑运算符通常用来组合多个表达式,逻辑运算符的运算结果是一个布尔值,只能有两种结果, true / false。
下表中列举了 JavaScript 中支持的逻辑运算符:
运算符名称示例&&逻辑与x && y 表示如果 x 和 y 都为真,则为真II逻辑或x II y 表示如果 x 或 y 有一个为真,则为真!逻辑非!x 表示如果 x 不为真,则为真
如果你想减少嵌套 if…else 或 switch case,你可以简单地使用基本的逻辑运算符AND/OR。
> 逻辑与运算(AND)
逻辑与运算
(&&)
是
AND
布尔操作。只有两个操作数都为
true
时,才返回
true
,否则返回
false
。
let user;//定义变量,为空,转换为布尔值,为 falselet msg =(!user && console.log("没有赋值"));// 返回提示信息“没有赋值”, 并且msg 值为 undefined。原因是 console.log() 为一个函数,无返回值。 // ----- 等效于 -----let user;//定义变量if(!user ){//条件判断
console.log("变量没有赋值");}
实际运行 – 基于谷歌浏览器控制台
// ① 情景一let user;//定义变量,为空,转换为布尔值,为 falselet msg =(!user && console.log("没有赋值"));// 输出 -> 没有赋值
console.log(msg)// 输出 -> undefined// ② 情景二let user;let msg =(!user &&false);
console.log(msg)// 输出 -> false// ③ 情景三let user;let msg =(!user &&(()=>{
console.log('方法内输出');returnfalse;}));
console.log(msg)/* 输出
() => {
console.log('方法内输出');
return false;
}
*/// ④ 情景四let user;let msg =(!user &&(()=>{
console.log('方法内输出');returntrue;}));
console.log(msg)/* 输出
() => {
console.log('方法内输出');
return true;
}
*/// ⑤ 情景五let user =0;let msg =( user &&(()=>{
console.log('方法内输出');returntrue;}));
console.log(msg)// 输出 undefined
如果变量 user 的值为
0
或
空字符串
等
假值转换为布尔值
时,则为 false,
那么当变量赋值之后,依然提示变量没有赋值
。因此,在设计时必须确保逻辑与左侧的表达式返回值是一个可以预测的值。
> 逻辑或运算(OR)
逻辑或运算||,是布尔值
OR
操作。如果两个操作数都为
true
,或者其中一个为
true
,就返回
true
,否则就返回
false
。
这里需要注意的一点是:逻辑或也是一种
短路逻辑
,如果左侧表达式为
true
,则直接短路返回结果,
不再运算右侧表达式
。运算逻辑如下:
- 第
1
步:计算第一个操作数(左侧表达式)的值。 - 第
2
步:检测第一个操作数的值。如果左侧表达式的值可转换为 true,那么就会结束运算,直接返回第一个操作数的值。 - 第
3
步:如果第一个操作数可以转换为 false,则计算第二个操作数(右侧表达式)的值。 - 第
4
步:返回第二个操作数的值。
使用案例
let personArr =[{name:null,age:18,youth:'未成年'},{name:'张三',age:25,youth:''}]
personArr.forEach(item=>{
item.youth = item.youth ||( item.age >=18?'成年':'未成年')
item.name = item.name ||'匿名'/*
其实这里可以用三元来写, 或者是if来判断,但是最为简洁就是 ||。
下面写一下,等价于:
*/
item.name = item.name ? item.name :'匿名'if(!item.name){
item.name ='匿名'}});
其实逻辑运算符还能有许多混合运用方法,但是大致语法就是上面描述的了! 具体还得根据实际情景来运用! 大伙可以去控制台练练手…
逻辑与和逻辑或运算符具有以下 2 个特点:
- 在逻辑运算过程中,临时把操作数转换为布尔值,然后根据布尔值决定下一步的操作,但是不会影响操作数的类型和最后返回结果。
- 受控于第一个操作数,可能不会执行第二个操作数。
> 逻辑非运算(NOT)
逻辑非运算
!
,是布尔取反操作(
NOT
)。作为一元运算符,直接放在操作数之前,
把操作数的值转换为布尔值
,然后取反并返回。
逻辑非运算相对较为简单,直接上案例。
实际案例
console.log(!{});//如果操作数是对象,则返回false
console.log(!0);//如果操作数是0,则返回true
console.log(!(n =5));//如果操作数是非零的任何数字,则返回false
console.log(!null);//如果操作数是null,则返回true
console.log(!NaN);//如果操作数是NaN,则返回true
console.log(!Infinity);//如果操作数是Infinity,则返回false
console.log(!(-Infinity));//如果操作数是-Infinity,则返回false
console.log(!undefined);//如果操作数是undefined,则返回true
tips: 当对某一内容或者表达式进行两次逻辑非运算时,就相当于把操作数转换为布尔值。
⌨️ 6、删除重复值(技巧)
在开发中,我们时常会遇到一些需要去重数据的情景。
正常情况下,我们可以将
indexOf()
与
for
循环一起使用,该循环返回第一个找到的索引。或者可以用 较新的
includes()
从数组中返回布尔值
true / false
以找出/删除重复项。
但是为了提高效率,单纯用for + indexof() / includes(),显然不太简洁,也不高效。 不妨看看以下两种方法:
const array =[5,4,7,8,9,2,7,5];// 利用 filter 函数 和 indexof() 直接筛选 数据const newArr = array.filter((item, index, arr)=> arr.indexOf(item)=== index);// 或者用 ES6 中新出的 Set对象,利用其特性,进行数组去重const nonUnique =[...newSet(array)];// 输出: [5, 4, 7, 8, 9, 2]
⌨️ 7、创建计数器对象 或 映射
在处理数据的时候,有些数据需要记录一些数据的出现次数(
类似某些日志数据、状态出现次数等等
)。这时,我们就需要用到一个
计数器对象
,来计算各个数据类型出现次数。正常情况下,计数器往往会被封装成一个公共方法(如果频繁使用的话)。 案例如下:
- 方法一: 利用循环 + 对象 记录
- 方法二: 利用循环 + Map 记录
const logData =[{id:'001',name:'张三',type:'借出书籍'},{id:'001',name:'张三',type:'归还书籍'},{id:'002',name:'李四',type:'借出书籍'},{id:'002',name:'李四',type:'借出书籍'}];// 方法一constcountObj_1=(data, idName_1, idName_2)=>{const obj ={};
data.forEach(item=>{
obj[item[idName_1]+'-'+ item[idName_2]]= obj[item[idName_1]+'-'+ item[idName_2]]+1||1})return obj;};// 方法二constcountObj_2=(data, idName_1, idName_2)=>{const countMap =newMap();
data.forEach(item=>{
countMap.set(item[idName_1]+'-'+ item[idName_2],(
countMap.has(item[idName_1]+'-'+ item[idName_2])?
countMap.get(item[idName_1]+'-'+ item[idName_2])+1:1))})return countMap ;};
console.log('方法一',countObj_1(logData,'id','type'))
console.log('方法二',countObj_2(logData,'id','type'))// 输出结果如下图
大致思路如上,能够通过这两种方法,去统计某种类型,某种数据出现的次数。希望大家灵活使用呀!
💬 小温有话说
暂时更新至此…内容较多,请大家稍安勿躁哈,后续将持续更新此文章! 能看到这里的,相信大家都非常有耐心学习的! 希望大伙给小温点实际编写呀
参考文献
本文编写思路参考自 华为云 - 《提高代码效率的 20 个JavaScript 技巧和窍门》 ,作者:海拥。
- 《reduce的介绍及用法》
- 《js中排序方法sort() 和 reverse()》
- 《javascript的逻辑运算符有哪些》
结合其他优秀的文章 及 个人见解编写! 若有遗漏或者错误没写好的地方,还请见谅! 接受评论 / 私聊 指出问题嗷! 如果觉得写得还不错,麻烦点赞支持一下小温啦!🥰
版权归原作者 技术宅小温 所有, 如有侵权,请联系我们删除。