【JavaScript前菜】解构赋值与rest参数、展开运算符之间的微妙关系

一、数组解构

 1 /**
 2  * 数组解构就是将数组展开后按顺序赋给变量
 3  * 其运作像极了调用方法传递参数时对数组的展开。
 4  */
 5 let arr = [1,2,3];
 6 // 下面这条语句是展开运算符和数组解构的结合使用
 7 let [a, ...others] = arr;
 8 console.log(a); // 1
 9 console.log(others); // [ 2, 3 ]
10 
11 // 运作方式类似于方法接受参数
12 function A(a, ...ohters) { //该方法用rest参数(...others)接受剩余实参
13   console.log(a); // 1
14   console.log(ohters); // [ 2, 3 ]
15 }
16 A(...arr); // 将数组展开后传递给方法

二、对象解构

 1 /**
 2  * 在这次对象解构中,仅看这次结果
 3  * 好像就是那么回事:像极了调用方法传递参数时对对象的展开。
 4  */
 5 let person = {
 6   name: '张三',
 7   age: 18,
 8   gender: '男'
 9 };
10 let {name, ...newObject} = person;
11 console.log(name); // 张三
12 console.log(newObject); // { age: 18, gender: '男' }

到这里,对解构赋值的使用语法有了更方便的理解,而且这样去理解好像并没有大毛病。

不过值得注意的是,一般的对象并不能这样展开:

 1 /**
 2  * 上面代码的解构的运作就像下面的一样,
 3  * 只不过下面这段代码是错误的。
 4  */
 5 let person = {
 6   name: '张三',
 7   age: 18,
 8   gender: '男'
 9 };
10 function B(name, ...newObject) {
11   console.log(name);
12   console.log(newObject);
13 }
14 // 错误的大意就是person不是可迭代对象
15 B(...person); // TypeError: Found non-callable @@iterator
16 
17 // 就像这样,也报同样的错
18 console.log(...person); // TypeError: Found non-callable @@iterator

这段代码的错误关系到展开运算符的语法问题,接下的交给更有权威的来🎉:

展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。(译者注: 字面量一般指 [1, 2, 3] 或者 {name: "mdn"} 这种简洁的构造方式)

...

在数组或函数参数中使用展开语法时, 该语法只能用于 可迭代对象

...

剩余语法(Rest syntax) 看起来和展开语法完全相同,不同点在于, 剩余参数用于解构数组和对象。从某种意义上说,剩余语法与展开语法是相反的:展开语法将数组展开为其中的各个元素,而剩余语法则是将多个元素收集起来并“凝聚”为单个元素。 请参考: 剩余参数。(注:这里说的剩余参数,也就是本文标题的rest参数)

引述自MDN

 

人人须日日改过,一旦无过可改,即一日无步可过矣。若发现不妥的点请务必指出,非常感谢。

posted @ 2021-12-27 19:05  不乏理想的三师弟  阅读(121)  评论(0)    收藏  举报