在函数定义中使用...语法传对象参数,为何会得到仅含该对象的数组?
容易搞混的核心点:同符号对应两种完全独立的JS语法
三个点...在JS中是功能方向完全相反、所属规则完全独立的两种语法,仅外观符号一致,初次接触很容易混淆:
- 写在函数形参列表最后位置的
...变量名,属于*剩余参数(Rest Parameter)*语法,并不归到你查看的展开语法规则里,自然在对应文档里找不到相关解释 - 写在函数调用的实参位置、数组字面量内部、对象字面量内部的
...,才是你查看文档对应的展开语法(Spread Syntax)
你写的代码的实际运行规则
你代码里的function abc(...aaa)是标准的剩余参数写法:
- 该语法的核心规则是:把函数调用时传入的、从当前形参位置开始的所有实参,全部收集打包成一个标准数组,赋值给紧跟在三个点后面的变量
aaa - 你调用
abc(obj1)时只传了1个实参,收集到的参数集合自然就是仅包含obj1的单元素数组,和你控制台看到的打印结果完全一致
两类语法的行为差异对照
两个语法虽然符号一样,但动作方向完全相反,举两个例子就能明确区分:
- 剩余参数是「收集合」:不管调用时传进来多少个零散实参,都会被三个点打包成数组收回来
比如你调用abc(obj1, 123, 'test'),aaa拿到的值就是[ {foo:'bar',x:42}, 123, 'test' ],和传几个参数无关,全量收集 - 展开语法是「拆集合」:把已经存在的数组/对象里的内容拆成零散的项传出去
比如你调用abc(...[obj1, 123, 'test'])时,这里的三个点才是展开语法,会把数组里的三个元素拆成独立的实参传给abc;此时函数内部的aaa依然会因为剩余参数的规则,收到这三个值组成的数组
补充:因为两个语法一个聚值、一个拆值,功能逻辑完全反向,所以官方文档也是把它们分成独立的条目撰写,并没有放在同一个章节下讲解,这也是你在展开语法文档里找不到相关说明的原因。
内容的提问来源于stack exchange,提问作者Nicolas S.Xu
相关产品推荐
相关产品推荐

