es6 新增了很多特性, 其中包括扩展运算符 ..., 扩展运算符使用场景比较多, 而且使用在不同的场景所表达的意思是不一样的. 总结如下
REST 参数
数组的扩展运算符
对象的扩展运算符
REST 参数
我们都知道 arguments 对象不是一个真正的数组, 所以 es6 推出了一种新的写法 如下:
这种在 function 形参中使用三个点 ... 表示用于获取函数的多余参数(把多余的参数序列转为一个数组), 这样就不需要使用 arguments 对象了. REST 参数的变量是一个数组, 该变量将一组参数放入数组中.
REST 参数只能是最后一个形参, 而且函数的 length 属性, 不包括 REST 参数.
数组的扩展运算符
在数组中使用 ... 扩展运算符, 就好像是 REST 参数的反运算 如下代码
- let array = [123,211,332,412,125,236,237,787]
- console.log(Math.max(...array))
把一个数组转为用逗号分隔的参数序列.
对象的扩展运算符
对象的扩展运算符分为两种, 一种是在解构赋值中, 如下代码
- let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
- console.log(z) // {a:3,b:4}
相当于把目标对象自身的所有可遍历, 但尚未被读取的属性, 分配到指定的对象上面. 所有的键和它们的值, 都会拷贝到新对象上面.
由于解构赋值要求等号右边是一个对象, 所以如果等号右边是 undefined 或 null, 就会报错, 因为它们无法转为对象.
解构赋值必须是最后一个参数, 否则会报错.
1 let { x, ...z, y } = { x: 1, y: 2, a: 3, b: 4 }; // 语法错误
另外一种是非解构赋值中, 如下代码
- let obj = {
- name: 'joel',
- age: '20',
- tempObj: {
- name: 'tempJoel'
- }
- }
- let temp = {...obj}
- temp.tempObj = 'joel29'
- console.log(temp) // {name: "joel", age: "20", tempObj: "joel29"}
- console.log(obj.tempObj) // {name: "tempJoel"}
取出参数对象的所有可遍历属性, 拷贝到当前对象之中. 如上代码, 这种拷贝不是浅拷贝, 只有在解构赋值的拷贝是浅拷贝, 如下代码
- let obj = {
- name: 'joel',
- age: '20',
- tempObj: {
- name: 'tempJoel'
- }
- }
- let temp = {...obj}
- temp.tempObj.name='tempJoel 修改'
- console.log(temp)
- console.log(obj)
我们是修改 temp 对象的 tempObj, 但是 obj 对象中的 tempObj 中的 name 也同步修改了.
在对象的扩展运算符中都是把目标的对象的属性拷贝到对象中, 如果是解构是存在浅拷贝
扩展运算符的本质
在 es6 中统一了遍历的接口 Iterator,Iterator 接口的目的, 就是为所有数据结构, 提供了一种统一的访问机制, 即 for...of 循环.
扩展运算符 (...) 内部其实是调用了 Iterator 接口.
总结
REST 参数
数组的扩展运算符
对象的扩展运算符
来源: https://www.cnblogs.com/CandyManPing/p/10520533.html