ES2015 / ES6中的扩展语法和剩余参数

83
我对ES2015中的扩展语法和剩余参数感到困惑。有人能用适当的例子解释它们之间的区别吗?

5
一个在调用点,另一个在参数列表中。对于数组来说,一个在字面量中,另一个则在解构表达式中。 - Bergi
1
有人可以解释一下为什么它被踩了吗? - Nur Rony
3
可能是因为没有表现出研究的努力。还有,你从哪里找到这些术语的?它们在哪里/如何被解释得如此糟糕,以至于你无法区分它们? - Bergi
2
@Bergi 个人认为,您的评论提供了比被接受的答案更多的见解,仅仅简单地陈述“扩展”与“折叠”并不能说明它们的用例,谢谢 ;) - Allen
4
我可能不会将这个问题作为重复问题关闭, React 中的三个点是什么意思?. 为什么? 因为这个问题显式地涉及到 rest 参数语法和 spread 语法,而另一个问题主要涉及 spread 语法。 比关闭其中一个问题更重要的是,它们现在彼此链接在一起。 这使得它们更容易找到。 - Henke
显示剩余4条评论
11个回答

141

使用展开运算符时,您将一个变量扩展为更多内容:

var abc = ['a', 'b', 'c'];
var def = ['d', 'e', 'f'];
var alpha = [ ...abc, ...def ];
console.log(alpha)// alpha == ['a', 'b', 'c', 'd', 'e', 'f'];

使用rest参数时,您将函数的所有其余参数折叠成一个数组:

function sum( first, ...others ) {
    for ( var i = 0; i < others.length; i++ )
        first += others[i];
    return first;
}
console.log(sum(1,2,3,4))// sum(1, 2, 3, 4) == 10;


const [a, b, ...c] = [1, 2, 3, 4, 5, 6, 7, 8, 9]是什么意思? - Yukulélé
6
@yukulélé这里的'rest'是指数组中除了'a'和'b'之外的所有元素。请按照“a”、“b”和其余的数组来理解它。 - ashish.gd
4
@Yukulélé的休息时间和c的值将会是[3,4,5,6,7,8,9]。 - Jaowat Raihan
您可以参考这篇博客了解剩余/扩展运算符的用法 - https://tejassavaliya.medium.com/es6-use-of-spread-rest-operator-in-javascript-f13b061b522f - Tejas Savaliya

97

ES6有一个新功能——三个点 ...

下面是我们如何使用这些点:

  1. 作为Rest/Collector/Gather
var [c, ...m] = [1,2,3,4,5]; // m -> [2,3,4,5]

这里 ...m 是一个收集器,它收集其余的参数。当我们在内部编写以下代码时:

var [c, ...m] = [1,2,3,4,5]; JavaScript 执行以下操作

var c = 1,
    m = [2, 3, 4, 5];
  1. 作为传播
var params = [ "hello", true, 7 ];
var other = [ 1, 2, ...params ]; // other => [1,2,"hello", true, 7]

在这里,...params 展开操作符将其所有元素都添加到 other 中。

JavaScript 内部执行以下操作:

var other = [1, 2].concat(params);

18

概述:

在JavaScript中,...是具有重载功能的,根据运算符使用的位置不同,它会执行不同的操作:

  1. 当在函数声明/表达式的参数中使用时,它将把剩余的参数转换为数组。这个变种被称为Rest参数语法。
  2. 在其他情况下,它将在期望零个或多个参数(函数调用)或元素(数组文字)的地方展开可迭代对象的值。这个变种被称为Spread语法。

示例:

Rest参数语法:

function rest(first, second, ...remainder) {
  console.log(remainder);
}

// 3, 4 ,5 are the remaining parameters and will be 
// merged together in to an array called remainder 
rest(1, 2, 3, 4, 5);

扩展语法:

// example from MDN:

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

// the numbers array will be spread over the 
// x y z parameters in the sum function
console.log(sum(...numbers));


// the numbers array is spread out in the array literal
// before the elements 4 and 5 are added
const newNumbers = [...numbers, 4, 5];

console.log(newNumbers);


扩展语法示例的第一部分似乎来自于JavaScript Demo: Expressions - Spread syntax。只要你进行归属,这没有任何问题。当其他人从我们这里获取内容时,这就是我们想让他们做的事情。请参见Attribution RequiredDefending Attribution Required - Henke

7

Javascript中的三个点 ( ... ) 运算符可以有两种不同的用法:

  1. 剩余参数:将所有剩余的元素收集到一个数组中。

var days = ["Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri"];
const [sat, sun, ...weekdays] = days;
console.log(sat); // "Sat"
console.log(sun); // "Sun"
console.log(weekdays); // ["Mon", "Tue", "Wed", "Thu", "Fri"]

  1. 展开运算符:允许可迭代对象(数组/对象/字符串)扩展为单个参数/元素。

var weekdays = ["Mon", "Tue", "Wed", "Thu", "Fri"];
var days = [...weekdays, "Sat", "Sun"]; 
console.log(days) // ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

请注意,展开运算符可以作为第一个元素,但是其余参数需要作为最后一个来收集剩余的元素。

1
剩余参数需要放在最后以收集其余元素。 ~ * ~ 已确认。 好主意!干杯。 - Henke

6
当我们在代码中看到“...”时,它可能是剩余参数(rest parameters)或者展开运算符(spread operator)。
区分它们有一个简单的方法:
当“...”出现在函数参数的结尾时,它被称为“剩余参数”,可以将列表中的剩下的元素收集到数组中。当“...”出现在函数调用等场景时,被称为“展开运算符”,可以将数组展开成列表。这两种模式的使用:
剩余参数用于创建接受任意数量参数的函数。展开运算符用于将数组传递给通常需要许多参数列表的函数。它们共同帮助我们轻松地在列表和参数数组之间进行转换。
更多信息请点击此处

3

在ES6中新增了这三个点...,它有两个含义,分别是展开运算符和剩余参数

展开运算符:您可以使用三个点来展开可迭代对象,我指的是数组字符串等作为参数。例如Math.max()函数期望不确定数量的参数,因此您可以使用展开运算符将元素展开为Math.max()函数的参数。以下是mdn的示例:

console.log(Math.max(1, 3, 2));
// expected output: 3

console.log(Math.max(-1, -3, -2));
// expected output: -1

var array1 = [1, 3, 2];

console.log(Math.max(...array1));
// expected output: 3

另一个使用案例是添加,例如有以下数组:

const videoGames = ['mario galaxy', 'zelda wind waker', 'ico'];

您可以将它添加到另一个数组中

const favoritesVideoGames = ['Shadow of the colosus', ...videoGames];

然后favoritesVideoGames的值为。
[ 'Shadow of the colosus', 'mario galaxy', 'zelda wind waker', 'ico' ]

关于Rest参数,这里是MDN的定义:

Rest参数语法允许我们将不确定数量的参数表示为数组。

这意味着您可以将多个元素打包到单个元素中。

这里是来自MDN的一个示例:

function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}

console.log(sum(1, 2, 3));
// expected output: 6

console.log(sum(1, 2, 3, 4));
// expected output: 10

我经常对这三个点感到困惑,这个示例@stephaniecodes提供帮助我记住它的逻辑。我提到了我从这个示例中汲取灵感来回答这个问题。
我希望它有用。

3

易记的............

如果三个点(...)在左侧,它是 Rest 参数,如果三个点在右侧,它是 Spread 参数。

记住LRS按字母顺序是 L 然后 R 再是 S

const [a,b,...c] = [1,2,3,4,5]     // (left) rest

const [d,e] = [1, ...c]             // (right) spread

2
基本上就像在Python中一样:
>>> def func(first, *others):
...    return [first, *others]
>>> func('a', 'b', 'c')
['a', 'b', 'c']

Python的例子并不能回答JavaScript问题,而且也没有解释restspread之间的区别,这并不能满足提问者的需求。 - josh1978

0

考虑3种情况

1] 不使用任何运算符

function add(x, y) {
  return x + y;
}

add(1, 2, 3, 4, 5) // returns 3  (function will takes first 2 arg only)

2] 带有剩余运算符

function add(...args) {
  let result = 0;

  for (let arg of args) result += arg;

  return result
}

add(1) // returns 1
add(1,2) // returns 3
add(1, 2, 3, 4, 5) // returns 15

- 我们可以将任意数量的参数收集到一个数组中

3] 使用展开运算符

const arr = ["Joy", "Wangari", "Warugu"];
const newArr = ["joykare", ...arr];

The value of newArr will be [ 'joykare', 'Joy', 'Wangari', 'Warugu' ]

另一个

function add(a, b, c) {
  return a + b + c ;
}
const args = [1, 2, 3];

add(...args);

-We have been using arrays to demonstrate the spread operator, 
but any iterable also works. So, if we had a 
string const str = 'joykare', [...str] translates to [ 'j', 'o', 'y', 'k', 'a', 'r', 'e' ]

0

关于这个我不理解在JavaScript中如何传递函数并返回参数

函数是一组指令,它接受一些输入并处理它们并返回结果。

在这里,我们有一个数组[1, 2, 3, 4, 5, 6],filter函数迭代每个元素并将每个元素传递给positive函数,如果它是偶数,则返回该数字,否则跳过它。

跟踪:

1 => Filter(1) => positive(1) => skips 1,
2 => Filter(2) => positive(2) => returns 2,
3 => Filter(3) => positive(3) => skips 3,
...
6 => Filter(6) => positive(6) => returns 6

因此结果为 [2, 4, 6]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接