在平时的业务代码中,常用的运算符有算数运算符、逻辑运算符等,而在 ES6 中,给我们提供了一种新的运算符——扩展运算符
扩展运算符只有一个,它的写法是...
,三个英文半角句号组成的运算符。下面就是本周关于扩展运算符学习的一些小结
扩展运算符在数组中的使用
作用:将一个数组转为用逗号分隔的参数序列
上面这句话的意思翻译成代码就是
console.log(...[1,2,3,4])
// 1 2 3 4
// 等价于 console.log(1,2,3,4)
看上去是不是很简单也很方便?之前,如果我们需要将一个数组中的所有元素打印出来,需要对这个数组进行遍历然后逐个打印,但是现在有了扩展运算符,一行代码全部搞定
那扩展运算符在数组中还有哪些用处呢?
简化数组push方法
向一个数组中push另一个数组中的元素
不使用...
——需要对另一个数组遍历后push,或者通过apply实现
使用...
——通过扩展运算符可直接将整个数组push
let a = []
let b = [1,2,3,4]
a.push(...b)
// apply 的实现方式:Array.prototype.push.apply(a, b)
既然是两个数组连接,那为什么不用concat
,而用push
呢?举个栗子,vue 中对数组元素的改变,只会对push
方法进行监听,而用concat
的话,数据模型被改变了,但是视图却不会改变
合并数组
const arr1 = [1]
const arr2 = [2,3]
const arr3 = [4,5,6]
const arr = [...arr1, ...arr2, ...arr3]
替代apply方法
有时候我们使用apply
方法只是为了将一个数组转为函数的参数,而这里...
则完美得替代了apply
的作用
function test (a, b, c) {...}
const args = ['a','b','c']
test(...args)
// 等价于 test.apply(null, args)
上面的情况还可以衍生到一般的情况——将一个数组通过扩展运算符解析为多个参数传入方法中,如:
// 有一个有数字组成的数组,需要获得这个数组中的最大值
const nums = [1,2,3,4]
Math.max(...nums)
// 等价于 Math.max(1,2,3,4)
将字符串转为数组
[...'hello world']
// ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
[...'hello world'].reverse().join('')
// "dlrow olleh"
扩展运算符在对象中的使用
作用:将目标对象中的所有可遍历属性取出,并拷贝到当前对象中
let obj1 = {key1: 'value1', key2: 'value2'}
let obj2 = {
key3: 'value3',
...obj1
}
console.log(obj2)
// {key3: "value3", key1: "value1", key2: "value2"}
// 等价于 Object.assign({key3: 'value3'}, obj1)
从上面的代码中,我可以想到,...
也可以用来合并两个对象
let total = {...a, ...b}
// 上面代码中 a 和 b 是两个对象
不管是合并还是拷贝,如果把自定义的属性扩展运算符中的属性同名,则后者会覆盖前者的值
还是以上面obj1
和obj2
为例:
// 自定义属性在扩展运算符后
obj2 = {
...obj1,
key2: 'value3'
}
// {key1: "value1", key2: "value3"}
// key2 被覆盖
// 自定义属性在扩展运算符前
obj2 = {
key1: 'value3',
...obj1
}
// {key1: "value1", key2: "value2"}
// key1 被覆盖
其他
扩展运算符后面是不是只可以跟随数组和对象呢?并不是
- 可以跟随有 Iterator 接口的对象
- 可以跟随表达式,但是需要返回数组、对象或有 Iterator 接口的对象
什么是具有 Iterator 接口的对象?下次再说:)