本文最后更新于:2020年12月25日 上午
场景
在今天写 JavaScript 函数时,发现了一个有趣的技巧。
在此之前,吾辈想知道泥萌需要默认值的时候是如何做的呢?
例如下面的函数 print
,吾辈需要在没有给定参数 user
的情况下,给出合适的输出
1 2 3 4 5 6 7 8 9 10 11 12
| function print(user) { if (!user) { user = {} } if (!user.name) { user.name = '未设置' } if (!user.age) { user.age = 0 } console.log(`姓名:${user.name},年龄:${user.age}`) }
|
那么,我们应该怎么优化呢?
- 三元表达式
||
/ &&
赋予默认值
Object.assign()
合并对象
我们分别来实现一下
三元表达式实现
1 2 3 4 5 6 7 8
| function print(user) { user = user ? user : {} console.log( `姓名:${user.name ? user.name : '未设置'},年龄:${ user.age ? user.age : 0 }`, ) }
|
||
/ &&
赋予默认值
1 2 3 4 5
| function print(user) { console.log( `姓名:${(user || {}).name || '未设置'},年龄:${(user || {}).age || 0}`, ) }
|
使用 &&
也可以
1 2 3 4 5 6 7
| function print(user) { console.log( `姓名:${(user && user.name) || '未设置'},年龄:${ (user && user.age) || 0 }`, ) }
|
||
/ &&
解释
||
用来取默认值,避免太多的 if
判断。例如对于 a || b
我们可以认为:如果 a
为空,则赋值为 b
&&
用来连续执行,避免深层嵌套的 if
判断。例如对于 a || b
,我们可以认为:如果 a
不为空,则赋值为 b
注:||/
&&` 非常适合简单的默认值赋值,但一旦设置到深层嵌套默认值就不太合适了
Object.assign()
合并对象
1 2 3 4 5 6 7 8
| function print(user) { _user = { name: '未设置', age: 0, } user = Object.assign(_user, user) console.log(`姓名:${user.name},年龄:${user.age}`) }
|
可以看出
- 三元表达式的方式方式明显有点繁琐
||
/ &&
很好很强大,缺点是看起来很不直观,而且容易混淆
Object.assign()
合并对象的方式应该算是最好的了,然而是在方法内部进行的初始化,作为调用者除非查看文档或源码才能知道
那么,有没有更好的解决方案呢?
解构赋值
解构赋值是 ES6 的一个新的语法,具体可以查看 MDN。
下面是一些简单的解构赋值操作
数组解构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| var arr = [1, 2, 3, 4] var [first, second, ...remaining] = arr
function join(...arr) { return arr.join(', ') }
join(...arr)
var [, , ...remaining] = arr
var [first = 1, second = 2, ...remaining] = [] var a = 1, b = 2
;[a, b] = [b, a]
|
对象解构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| var user = { id: 1, name: '未设置', age: 0, sex: false, }
var { name, age, ...rest } = user
var { name: newName, age: newAge } = user
var { name = '未设置', age = 0 } = {}
var { name: newName = '未设置', age: newAge = 0 } = user
var key = 'name' var { [key]: name } = user
var users = [ { name: '琉璃', age: 17, }, { name: '楚轩', age: 23, }, ] users.map(({ name, age }) => `name: ${name}, age: ${age}`).join('\n')
function print({ name = '未设置', age = 0 } = {}) { console.log(`姓名:${name},年龄:${age}`) }
|
啊嘞,吾辈好像不知不觉间把解决方案写出来了。。。?
分析
让我们好好看下这段代码
1 2 3
| function print({ name = '未设置', age = 0 } = {}) { console.log(`姓名:${name},年龄:${age}`) }
|
一眼看过去,是不是感觉很直观,如果稍微了解一点 ES6 就能瞬间明白这是解构赋值以及默认参数
我们分析一下具体流程
调用 print
函数
检查参数是否为有值,没有的话设置默认值 {}
相当于
1 2 3
| if (!user) { user = {} }
|
解构参数,检查解构的属性是否有值,没有的话设置默认值
相当于
1 2 3 4 5 6 7 8 9 10 11 12
| var name if (!user.name) { name = '未设置' } else { name = user.name } var age if (!user.age) { age = 0 } else { age = user.age }
|
进入函数内部
关键就在于第 2,3 步,默认参数 和 解构赋值 都是 ES6 的新特性,善于使用能大大简化代码的繁琐性。
希望有更多的人能够学会怎么使用,让我们早日抛弃 babel 吧 (*^ ▽ ^)/