在 JavaScript 中多次使用展开运算符

问题描述 投票:0回答:4

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

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

console.log(arr); // Array [[[1, 2, 3]]]
console.log(...arr); // Array [[1, 2, 3]]
console.log(...(...arr));
// Uncaught SyntaxError: Unexpected token '...'

我预料到了:

console.log(...(...arr)); // Array [ 1, 2, 3 ]
javascript ecmascript-6 spread-syntax
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

3
投票

根据this,扩展语法输入是可迭代的(例如数组),但其产生的输出是不可迭代的(例如非数组)。所以问题是,在外部扩展语法

...
作为输入中,你放置了不可迭代的东西(
...arr
),这会导致 SyntaxError。要展平您的数组,您可以使用展平(如果您将 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));


1
投票

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

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

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


1
投票

不回答你的问题,但是 - 一般来说,三点

...
语法可以 应用于 可迭代对象 - 数组类数组对象

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

我不会回答问题为什么
但下面的代码片段显示

...[].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; }

© www.soinside.com 2019 - 2024. All rights reserved.