JavaScript … 延展操作符(Spread operator)
上一篇文章 解决 Node.js 项目报 SyntaxError: Unexpected token … 错误 - 干志雄的博客 就是因为…操作符导致运行报错了,本文将介绍…操作符和解答上一篇文章中的思考问题。
… 操作符英文叫 Spread operator,即延展操作符。该操作符从 ES6 开始支持。ES9 中也新增了些特性。
ES6 延展操作符(Spread operator)的特性
ES6 即 ECMAScript 2015 规范。
延展操作符…,从ES6开始添加的。
- 可以在函数调用/数组构造时, 将数组表达式或者 string 在语法层面展开;
- 还可以在构造对象时, 将对象表达式按key-value的方式展开。
语法
函数调用
1 | myFunction(...iterableObj); |
数组构造或字符串:
1 | var iterableObj = [0, 1, 2, 3]; |
应用场景
在函数调用时使用延展操作符
1 | function sum(x, y, z) { |
Rest 参数和扩展运算符
ES2015 引入了 Rest 参数和扩展运算符。三个点(…)仅用于数组。Rest 参数语法允许我们将一个不定数量的参数表示为一个数组。
1 | function restParam(p1, p2, ...p3) { |
展开操作符
展开操作符以相反的方式工作,将数组转换成可传递给函数的单独参数。例如Math.max()返回给定数字中的最大值:
1 | /** |
1 | const values = [99, 100, -1, 48, 16]; |
构造数组
没有展开语法的时候,只能组合使用 push,splice,concat 等方法,来将已有数组元素变成新数组的一部分。有了展开语法, 构造新数组会变得更简单、更优雅。
和参数列表的展开类似, … 在构造字数组时, 可以在任意位置多次使用。
1 | const stuendts = ['Jine','Tom']; |
连接多个数组
1 | var arr1 = [0, 1, 2]; |
数组拷贝
展开语法和 Object.assign() 行为一致, 执行的都是浅拷贝(只遍历一层)。
1 | var arr = [1, 2, 3]; |
在React中的应用
通常我们在封装一个组件时,会对外公开一些 props 用于实现功能。大部分情况下在外部使用都应显示的传递 props 。但是当传递大量的props时,会非常繁琐,这时我们可以使用 …(延展操作符,用于取出参数对象的所有可遍历属性) 来进行传递。
一般情况下我们应该这样写。
1
<CustomComponent name ='Jine' age ={21} />
使用 … ,等同于上面的写法。
1
2
3
4
5const params = {
name: 'Jine',
age: 21
}
<CustomComponent {...params} />配合解构赋值避免传入一些不需要的参数。
1
2
3
4
5
6
7
8
9
10
11var params = {
name: '123',
title: '456',
type: 'aaa'
}
var { type, ...other } = params;
<CustomComponent type='normal' number={2} {...other} />
//等同于
<CustomComponent type='normal' number={2} name='123' title='456' />
ES9延展操作符(Spread operator)的特性
ES9 即 ECMAScript 2018 规范。
ES9 中 Spread operator 有关联的特性是:
- object spread properties,即延展操作符增加了对对象的支持。
- object rest properties,即 Rest 参数添加了对对象的支持。
语法
构造对象时,进行克隆或者属性拷贝。
但是这只是一个对象的浅拷贝。因此,如果一个对象 A 的属性是对象 B ,那么在克隆后的对象 cloneB 中,该属性指向对象 B。
1
2
3
4> let a = 'a'; let b = {...a}
undefined
> b
{ '0': 'a' }
1 | > let array = ['a', 'b', 'c']; let copyArray = {...array} |
1 | > let obj = {a: 0, b: 1, c: 2}; let objClone = {...obj}; |
合并对象
1 | var obj1 = { foo: 'bar', x: 42 }; |
对象解构
提供了和数组一样的Rest参数()和展开操作符。
1 | const myObject = { |
或者你可以使用它给函数传递参数:
1 | function restParam({ a, ...x }) { |
跟数组一样,Rest 参数只能在声明的结尾处使用。
此外,它只适用于每个对象的顶层,如果对象中嵌套对象则无法适用。
如何知道node的版本是否支持ES特性
通过 node.green 这个网站可以查询到 ES 特性是否支持 node 版本。
例如,我现在用的 node 版本为 v6.9.2,我要判断是否支持 object spread properties 这个特性?
其实有两个方法。
通过node.green查找
通过 node.green,找到 object spread properties,可以看到只有 8.6 及以上的版本才支持。
通过代码测试验证
在 node 版本为 6.9.2 下验证。
可以看到
let b = {...a}
输入回车后,只有三个.,没有任何提示了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18$ node
> let a = 'a'
undefined
> let b = {...a}
...
> b
ReferenceError: b is not defined
at repl:1:1
at sigintHandlersWrap (vm.js:22:35)
at sigintHandlersWrap (vm.js:96:12)
at ContextifyScript.Script.runInThisContext (vm.js:21:12)
at REPLServer.defaultEval (repl.js:313:29)
at bound (domain.js:280:14)
at REPLServer.runBound [as eval] (domain.js:293:12)
at REPLServer.<anonymous> (repl.js:513:10)
at emitOne (events.js:101:20)
at REPLServer.emit (events.js:188:7)
>在 node 版本为 10.16.3 下验证。
木有问题,测试通过。
1
2
3
4
5
6
7
8
9
10
11
12
13# ganzhixiong @ ganzhixiongdeMacBook-Pro-3 in ~/Documents/blog on git:master x [23:42:57]
$ node -v
v10.16.3
# ganzhixiong @ ganzhixiongdeMacBook-Pro-3 in ~/Documents/blog on git:master x [23:43:01]
$ node
> let a = 'a'
undefined
> let b = {...a}
undefined
> b
{ '0': 'a' }
>
参考链接
相信你看完本文,应该已经知道上一篇文章 解决 Node.js 项目报 SyntaxError: Unexpected token … 错误 - 干志雄的博客 最后留下的思考问题的答案了。
JavaScript … 延展操作符(Spread operator)