21

为什么不能多次使用传播运算符?

let arr = [[[1, 2, 3]]];

console.log(arr); // Array [ Array[1] ]
console.log(...arr); // Array [ Array[3] ]
console.log(...(...arr));
// SyntaxError: expected '=>' after argument list, got ')'

我希望:

console.log(...(...arr)); // Array [ 1, 2, 3 ]
4

4 回答 4

18

为什么不能多次使用传播运算符?

...不是运算符。(...arr)不是有效的 JavaScript。...只允许在数组字面量和参数列表中使用,但这些是语法的特殊形式(请注意...下面的生产规则)。

数组字面量

ArrayLiteral :
  [ Elision_opt ]
  [ ElementList ]
  [ ElementList , Elision_opt ]

ElementList :
  Elision_opt SpreadElement
  ElementList , Elision_opt SpreadElement

SpreadElement:
  ... AssignmentExpression

论据

Arguments :
  ( )
  ( ArgumentList )

ArgumentList :
  AssignmentExpression
  ... AssignmentExpression
  ArgumentList , AssignmentExpression
  ArgumentList , ... AssignmentExpression
于 2016-01-26T17:52:52.640 回答
1

因为 ...arr 不像在正常情况下返回值的函数(您可以通过在控制台中键入 ...[[1,2,3]] 来测试它,如果 ... 像正常函数一样运行我们预计回报为 [1 2 3]。因此,您不能链接点差。来自 MDN:

扩展运算符允许在需要多个参数(用于函数调用)或多个元素(用于数组字面量)的地方扩展表达式。

因此,传播需要发生在数组字面量、对象字面量(如果使用 obj spread,即 ES7)或函数调用中所以你可以做 console.log(...[].concat(...arr))

于 2016-01-26T17:45:49.697 回答
1

据此扩展语法输入是可迭代的(例如数组),但它产生的输出是不可迭代的(例如非数组)。所以问题是,在外部扩展语法作为输入中,您放置了导致 SyntaxError...的不可迭代的东西 ( )。...arr要平整您的数组,您可以使用 flat(如果您将 Infinity 改为 2,那么您将平整任何嵌套数组)

arr.flat(2)

let arr = [[[1, 2, 3]]];
console.log(arr.flat(2));

let arr2 = [[1,2,[3,4,[5,[6]]]], [[7,[8]],9]];;
console.log(arr2.flat(Infinity));

于 2019-02-18T12:22:35.030 回答
0

不回答您的问题,但是-通常,三点 ...语法可以应用于可迭代对象-数组类似数组的对象

为什么不能多次使用传播运算符?

我不会回答为什么这个问题。
但下面的代码片段显示,它...[].concat(...arr)实现了你期望通过做得到的东西...(...arr)。它的灵感来自此评论

const arr = [[[1, 2, 3]]];

console.log(JSON.stringify(arr));                  // [[[1,2,3]]]
console.log(JSON.stringify(...arr));               // [[1,2,3]]
// console.log(JSON.stringify(...(...arr)));       // SyntaxError: expect...
console.log(JSON.stringify(...[].concat(...arr))); // [1,2,3]
console.log(...[].concat(...[].concat(...arr)));   // 1 2 3
.as-console-wrapper { max-height: 100% !important; top: 0; }

于 2021-03-15T14:31:51.433 回答