15个让新手代码更优雅的小Tips

116 阅读4分钟

前言

优雅的代码往往能够让人眼前一亮,原来实现xxx还能这么搞?下面的一些操作,老玩家们已经用得炉火纯青,新手们可不能落下,也得点亮一波小技能!

新增的符号

1. 使用 ** 代替数值的n方函数 Math.pow()

console.log(2 ** 3) // 8 等同于Math.pow(2, 3)

2. 使用 ?. 来避免访问属性出现错误

当左侧的对象为null或者undefined时,?. 将不再继续往下执行

let obj = {}
console.log(obj.user.id) // Cannot read properties of undefined (reading 'id')
// 为了避免报错导致程序无法继续执行,有以下解决方法
// 常规判断
console.log(obj.user&&obj.user.id)
// 使用 ?.
console.log(obj.user?.id)

兼容性: Snipaste_2023-02-02_17-20-37.png

3. 使用 ?? 排除 nullundefined,相对于操作符||可以保留 0、false等值

当左侧的对象为null或者undefined时,返回右侧的值,否则返回左侧的值;

 let a1 = 0 || 1
 let a2 = 0 ?? 2
 let a3 = null ?? 3
 let a4 = undefined ?? 4
 console.log(a1,a2,a3,a4)
 // 1, 0, 3, 4

兼容性同 ?.

字符串相关

4. 模板字符串(使用反引号 ` )

反引号便于在字符串中插入变量,相对于以前使用 +号 进行拼接来得更加简洁和方便。 使用 ${} 即可在模板字符串中插入变量,也可以执行一些 js表达式

let name = '小明'
console.log(`你好,${name}`) // 你好,小明
console.log(`1 + 2 = ${1+2}`) // 1 + 2 = 3 (模板字符串中的空格/换行也会原封不动保留)
let age = 18
console.log(`小明${age>=18?'成年了':'未成年'}`) // 在模板字符串中使用三元表达式

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6e7e129ee15a4fd293628b431a1a45b6~tplv-k3u1fbpfcp-watermark.image?)

5. 字符串includes 方法(es6新增)

与数组的 includes 方法作用类似,返回boolean值。如果只需判断字符串中是否存在另一个字符串,比 indexOf(存在返回索引,不存在返回-1) 更加直观。

let str1 = 'abcd', str2='a'
// 判断str1是否包含str2
console.log(str1.indexOf(str2) > -1) // true
console.log(str1.includes(str2)) // true

6. 使用正则表达式操作字符串

字符串中支持正则表达的方法:replace()split()match()search()replaceAll()matchAll()

🌰eg1: 下面的例子为利用正则表达式 切割字符串中1个及以上的空格。

'space1 space2  space3   space4'.split(/ +/)
// 结果:[space1,space2,space3,space4]

🌰eg2: 下面利用正则表达式配合字符串方法 获取URL上的参数

注: 这里由于正则表达式里面涉及到变量,因此必须要使用到正则表达式的构造函数来构造正则表达式。

function getParam(key, url) {
    let reg = new RegExp(`${key}=(.*?)(&|#|\\?|$)`)
    let value = url.match(reg)?url.match(reg)[1]:''
    return value
}
getParam('code', 'https://juejin.cn/?code=123456&id=2')
// 123456
getParam('id', 'https://juejin.cn/?code=123456&id=2')
// 2

数组

7. 使用...扩展运算符代替canact()

let arr1 = [1,2], arr2 = [3,4], arr3 = [5,6]
console.log(arr1.conact(arr2).conact(arr3)) // [1,2,3,4,5,6]
console.log([...arr1, ...arr2, ...arr3]) // [1,2,3,4,5,6]

8. 使用...扩展运算符解构数组作为入参

Math.max(...[1,2,3]) //3 等同于Math.max(1,2,3)

9. 使用...扩展运算符进行浅拷贝

let arr = [1,2,3];
let newArr = [...arr];
arr !== newArr

let obj1 = {id:1}, obj2 = {name:2}
let newObj = {...obj1, ...obj2} // {id:1, name:2}  对象合并

10. 利用 map() 从数组里的对象中提取某个字段作为数组

如果想要从对象数组中 取到某个字段来进行拼接,那么就可以使用 map() 配合 join() 来处理(通常用于页面dom元素展示多个名称)

let arr = [
            {id:1,name:'小明'},
            {id:2,name:'小红'},
            {id:3,name:'小华'}
          ]
let nameList = arr.map(item => item.name) // ['小明','小红','小华']
// 链式处理
let nameStr = arr.map(item => item.name).join(',') // '小明,小红,小华'

另外,使用 map 会分配空间返回一个新的数组,如果只是单纯循环处理数组不需要返回新数组,请使用 forEach

11. 利用 reduce() 累加数组中的某个字段

reduce 接受一个函数和一个初始值,函数中第一个参数为上一次执行的结果,利用reduce还可以进行数组合并等等

let arr = [
           {id:1,name:'小明'},
           {id:2,name:'小红'},
           {id:3,name:'小华'}
         ]
arr.reduce((a,b)=>a+b.id,0) // 6

12. 数组扁平化 flat() 传入的参数代表扁平化的层数

// 入参为扁平化的层数
[1, 2, [3, [4, [5]]]].flat(1) // [1,2,3,[4,[5]]] 
[1, 2, [3, [4, [5]]]].flat(2) // [1,2,3,4,[5]] 
[1, 2, [3, [4, [5]]]].flat(Infinity) // [1,2,3,4,5] 

对象

13. 利用键值对映射取值,减少大量的 if...else...式代码

let key = 'key2', val
if (key === 'key1') {
    val = 'value1'
} else if(key === 'key2') {
    val = 'value2'
} else if(key === 'key3') {
    ...
}
// 键值对写法
let map = {
    key1:'value1',
    key2:'value2',
    key3:'value3'
}
val = map[key] // value2

同理,以上方法不仅仅用于字符串的赋值,也可以用于对应方法的执行

function fn1() {console.log(1)}
function fn2() {console.log(2)}
...
let key = 'key2', val
if (key === 'key1') {
   fn1()
} else if(key === 'key2') {
   fn2()
} else if(key === 'key3') {
   ...
}
let map = {
    key1:fn1,
    key2:fn2,
    key3:fn3
}
map[key]() // 2

14. 使用变量定义对象键值

如果key值是变量,对对象的属性赋值时,除了使用中括号[], 还可以直接定义在对象中。

let key = 'id'
let obj1 = {}
obj1[key] = 1 // {id:1}

let obj2 = {
    [key]:2
} // {id:2}

15. 获取对象的键数组/值数组

利用es6新增的api可以让我们很容易就拿到对象的键值集合

let obj = {id:1,name:2,age:3}
// 获取keys数组
console.log(Object.keys(obj)) // ['id', 'name', 'age']
// 获取values数组
console.log(Object.values(obj)) // [1, 2, 3]
// 获取键值数组
console.log(Object.entries(obj)) // [['id', 1], ['name', 2], ['age', 3]]

小结

对于ES6新增的一些语法还不熟悉的小伙伴们建议熟读一下阮一峰老师的 《ECMAScript 6 入门》,相信读完之后的你们能对代码编写有更好的见解与技巧。