在javascript中多次使用spread运算符?

时间:2016-01-26 17:04:32

标签: javascript ecmascript-6 spread-syntax

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

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 个答案:

答案 0 :(得分:16)

  

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

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

ArrayLiteral

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

ElementList :
  Elision_opt SpreadElement
  ElementList , Elision_opt SpreadElement

SpreadElement:
  ... AssignmentExpression

Arguments

Arguments :
  ( )
  ( ArgumentList )

ArgumentList :
  AssignmentExpression
  ... AssignmentExpression
  ArgumentList , AssignmentExpression
  ArgumentList , ... AssignmentExpression

答案 1 :(得分:0)

因为... arr不像是在正常情况下返回值的函数(你可以通过在控制台中输入... [[1,2,3]]来测试它,如果......操作像一个正常的函数我们期望返回[1 2 3]。因此你不能链接点差。来自MDN:

  

扩展运算符允许表达式在某些地方展开   其中多个参数(用于函数调用)或多个元素   (对于数组文字)是预期的。

问题,点差需要在数组文字,对象文字(如果使用obj spread,即ES7)或函数调用中发生 所以你可以做console.log(... []。concat(... arr))

答案 2 :(得分:0)

根据this,扩展语法输入是可迭代的(例如,数组),但是其产生输出是不可迭代的(例如,非数组)。因此,问题在于,在外部扩展语法...中,您输入了会引起SyntaxError的不可迭代对象(...arr)。要展平数组,可以使用展平(如果将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));

答案 3 :(得分:0)

不能回答您的问题,但是 - 一般来说,三个点 ... 语法可以 应用于可迭代对象 - 数组类数组对象

<块引用>

为什么不能多次使用扩展运算符?

我不会回答问题为什么
但下面的片段显示 ...[].concat(...arr) 实现了您的目标 期望通过执行 ...(...arr) 获得。 它的灵感来自this comment

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; }