我相信你一定或多或少的接触或使用过 JS
中的扩展操作符(Spread Operator
),在基本形式中,扩展操作符看起来像三个点,比如下这样:
1 | [...arr]; |
而实际上,它也就是这么用的,但是如果事情有这么简单,就不用我在这里写了。扩展操作符给我最大的印象就是,这玩意还挺方便的,然而最近写代码的时候经常性的遇到需要使用扩展操作符的场景,所以我干脆在网上找了些资料,把平时常见的应用场景给罗列了下,发现这个操作符是真的强大,有多强大?来看看下面这些用法吧。
- 字符串转数组
字符串转数组最普遍的做法是这样:
1 | let str = "hello"; |
而使用了扩展操作符后可以这样:
1 | let str = "hello"; |
- 将类数组转换为数组
在 JS
中有一种数据结构叫做 NodeList
,它和数组很相似,也被叫做“类数组”,类数组是什么?在 MDN
中是这么定义它的:
类数组:拥有一个
length
属性和若干索引属性的任意对象。
类数组有哪些呢?以下这些可以看成是类数组:
NodeList
:document.querySelectorAll()
返回的对象;HTMLCollection
:document.getElementsByTagName()
返回的对象;Arguments
:函数里的参数对象;
类数组没有数组的一些方法比如 push
、map
等,所以经常需要将它们转成数组,而通常我们是这么转化的:
1 | let nodeList = document.querySelectorAll("div"); |
而有了扩展操作符可以这么做:
1 | let nodeList = document.querySelectorAll("div"); |
- 向数组中添加项
往数组中添加几项通常这样操作:
1 | let arr = [5]; |
使用扩展操作符后:
1 | let arr = [3, 4]; |
- 拷贝数组和对象
通常拷贝一个数组,可以这么做:
1 | let arr = [1, 3, 5, 7]; |
但是有了扩展操作符,拷贝数组就能写得很简单:
1 | let arr = [1, 3, 5, 7]; |
同样的,扩展操作符还能拷贝对象。
拷贝对象的通常做法:
1 | let person = { name: "布兰", age: 12 }; |
有了扩展操作符,拷贝一个对象就相当方便了:
1 | let person = { name: "布兰", age: 12 }; |
注意:扩展操作符只能深拷贝结构为一层的对象,如果对象是两层的结构,那么使用扩展操作符拷贝会是浅拷贝。
- 合并数组或对象
数组合并通常是这么做的:
1 | let arr1 = [1, 3, 5]; |
使用扩展操作符后,可以这么写:
1 | let arr1 = [1, 3, 5]; |
对了,它除了能合并数组外还能合并对象呢。合并对象,通常的做法是:
1 | let p1 = { name: "布兰" }; |
用扩展操作符合并对象:
1 | let p1 = { name: "布兰" }; |
- 解构对象
经常我们给对象设置参数的时候会这么做:
1 | let person = { |
而有了扩展操作符,我们就可以这么写,不过其实如下这种写法并不是扩展操作符的写法 🤣,而是剩余操作符的写法,虽然写出来后看起来差不多,但就在操作对象这一点上,基本上可以认为它和扩展操作符是相反的操作,扩展操作符是用来展开对象的属性到多个变量上,而剩余操作符是用来把多个参数凝聚到一个变量上。
1 | let person = { |
- 给对象添加属性
给对象加属性通常这样加:
1 | let person = { name: "布兰" }; |
使用扩展操作符给对象添加属性:
1 | let person = { name: "布兰" }; |
关于使用扩展操作符给对象添加属性,这里有 2 个小技巧:
- 给新对象设置默认值:
1 | // 默认 person 对象的 age 属性值 为 12 |
- 重写对象属性
1 | let person = { name: "布兰", age: 12 }; |
- 设置对象
Getter
设置对象 Getter
通常做法是这样:
1 | let person = { name: "布兰" }; |
而有了扩展操作符后可以这么写:
1 | let person = { name: "布兰" }; |
- 将数组作为函数参数展开
如果我们有一个形参是多个参数的函数,但是当调用的时候发现入参却是一个数组,常规做法是这样:
1 | let arr = [1, 3, 5]; |
使用扩展操作符后,就简单多了:
1 | let arr = [1, 3, 5];实际上,它也就是这么用的,但是如果事情有这么简单,就不用我在这里写了。扩展操作符给我最大的印象就是,这玩意还挺方便的,然而最近写代码的时候经常性的遇到需要使用扩展操作符的场景,所以我干脆在网上找了些资料,把平时常见的应用场景给罗列了下,发现这个操作符是真的强大,有多强大?来看看下面这些用法吧。 |
- 无限参数的函数
如果有这么一个累加函数,他会把所有传递进来的参数都加起来,普通做法是把参数都整合到数组里,然后这样做:
1 | function doSum(arr) { |
如果参数不是数组,而是需要一个个传递,相当于函数必须支持无限参数,那可能会这么做:
1 | function doSum() { |
而有了扩展操作符,就简单多了:
1 | function doSum(...arr) { |
- 扩展函数的剩余参数
有的时候一个函数需要传递很多的参数,比如小程序页面(WePY
)的 onLoad
生命周期函数里就可能有很多别的页面传递过来的参数,然后还需要在函数里进行一些数据初始化工作,这样一来就会显得很臃肿不美观,比如:
1 | function init(a, b, x, y) { |
而使用了扩展操作符后,我们就可以按照业务把参数进行解构,把本该在一个函数里进行初始化的工作拆分成多个,可以这么做:
1 | function other(x, y) {} |
- 结合
Math
函数使用
比如当需要对一个数组求最大值的时候,通常会这么做:
1 | let arr = [3, 1, 8, 5, 4]; |
但是使用扩展操作符后,能够把给数组求最大值写得更加简洁:
1 | let arr = [3, 1, 8, 5, 4]; |
- 在
new
表达式中使用
假设有一个数组格式的日期,想要通过 Date
构造函数创建一个日期实例的话,可能会这么做:
1 | let arr = [2021, 1, 1]; |
而有了扩展操作符就简单多了:
1 | let arr = [2021, 1, 1]; |
总结
这个操作符真可谓使用简单无脑,但是功能效率上不得不说很强大,所以我们要做的就是只要记住在什么时候使用它就好了,于是乎为了让大家能更好的记住这 13
种使用场景,我特意做了一个图,方便大家记忆,是不是很贴?是的话请不要吝啬你的爱心,给个小星星 👍 吧,感谢感谢。以上这些只列了 13
种写法,我觉得作为一个这么强大的操作符,肯定有更多使用的场景,欢迎把你们知道的写到评论区吧。