在javascript中多次使用传播运算符?

IT技术 javascript ecmascript-6 spread-syntax
2021-03-05 02:05:28

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

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个回答

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

...不是运营商。(...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
@madox2:是的。我不知道是谁提出了术语“扩展运算符”,但它肯定不是 JavaScript 意义上的运算符。这只是一个令牌。
2021-04-23 02:05:28
@FelixKling 你能再解释一下吗?我看了你的回答很多次,但我不明白。
2021-05-09 02:05:28
我确信传播一个已经传播的数组不会评估,但事实证明我错了,因为它确实如此。这似乎是唯一正确的答案。+1
2021-05-14 02:05:28
您可能想支持我为澄清“运算符”一词而提出的问题:实际上,什么是运算符,什么不是运算符?
2021-05-14 02:05:28
@madox2:如果我们将运算符视为一种特殊形式的函数(在其他语言中也是如此),那么我们可以说我们可以在任何可以使用函数调用的地方使用运算符。例如,var foo = add(1, 2);我们可以写var foo = 1 + 2;. 但是,我们不能代替var foo = spread(arr);使用var foo = ...arr;没有独立的扩展运算符之类的东西,它只是数组初始值设定项和参数列表语法的扩展。当查看语言语法时,这一点就变得很清楚了。
2021-05-14 02:05:28

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

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

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

根据,扩展的语法输入是一个可迭代(例如阵列),但其产生的输出,其是非迭代(例如,非阵列)。所以问题是,在外部传播语法...作为输入时,你放置了...arr导致 SyntaxError 的不可迭代的东西 ( )。要扁平化数组,您可以使用扁平化(如果将 Infinity 放入 2,则将扁平化任何嵌套数组)

arr.flat(2)

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

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

我不会回答为什么
但下面的代码片段显示,...[].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; }