简体   繁体   English

ES2015 / ES6 中的Spread语法与Rest参数

[英]Spread Syntax vs Rest Parameter in ES2015 / ES6

I am confused about the spread syntax and rest parameter in ES2015.我对 ES2015 中的 spread 语法和 rest 参数感到困惑。 Can anybody explain the difference between them with proper examples?任何人都可以用适当的例子解释它们之间的区别吗?

When using spread, you are expanding a single variable into more:使用传播时,您将单个变量扩展为更多:

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

When using rest arguments, you are collapsing all remaining arguments of a function into one array:使用 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;

ES6 has new feature three dots ... ES6 新特性三点...

Here is how we can use these dots:以下是我们如何使用这些点:

  1. As Rest/Collector/Gather作为休息/收藏家/聚会
var [c, ...m] = [1,2,3,4,5]; // m -> [2,3,4,5]

Here ...m is a collector, it collects the rest of the parameters.这里...m是一个收集器,它收集其余的参数。 Internally when we write:当我们在内部编写时:

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

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

Here, ...params spreads so as to adding all of its elements to other在这里, ...params展开以便将其所有元素添加到other

Internally JavaScript does following JavaScript 在内部执行以下操作

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

Hope this helps.希望这可以帮助。

Summary:概括:

In javascript the ... is overloaded.在 javascript 中...是超载的。 It performs a different operations based on where the operator is used:它根据使用运算符的位置执行不同的操作:

  1. When used in function arguments of a function declaration/expression it will convert the remaining arguments into an array.当在函数声明/表达式的函数参数中使用时,它会将剩余的参数转换为数组。 This variant is called the Rest parameters syntax.此变体称为Rest 参数语法。
  2. In other cases it will spread out the values of an iterable in places where zero or more arguments (function calls) or elements (array literals) are expected.在其他情况下,它将在需要零个或多个参数(函数调用)或元素(数组文字)的地方散布可迭代对象的值。 This variant is called the Spread syntax.这种变体称为Spread语法。

Example:例子:

Rest parameter syntax:其余参数语法:

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

Spread syntax:传播语法:

 // 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 // xyz 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);

When we see "..." in the code, it is either rest parameters or the spread operator.当我们在代码中看到“...”时,它要么是其余参数,要么是展开运算符。

There's an easy way to distinguish between them:有一个简单的方法来区分它们:

When ... is at the end of function parameters, it's “rest parameters” and gathers the rest of the list into the array.当 ... 位于函数参数的末尾时,它是“其余参数”并将列表的其余部分收集到数组中。 When ... occurs in a function call or alike, it's called a “spread operator” and expands an array into the list.当 ... 出现在函数调用或类似情况中时,它被称为“扩展运算符”并将数组扩展到列表中。 Use patterns:使用模式:

Rest parameters are used to create functions that accept any number of arguments.其余参数用于创建接受任意数量参数的函数。 The spread operator is used to pass an array to functions that normally require a list of many arguments.展开运算符用于将数组传递给通常需要许多参数列表的函数。 Together they help to travel between a list and an array of parameters with ease.它们一起有助于轻松地在列表和参数数组之间移动。 For more information about this click here有关此的更多信息,请单击此处

Javascript's three dots ( ... ) operator can be used in two different ways: Javascript 的三个点 ( ... ) 运算符可以以两种不同的方式使用:

  1. Rest parameter : collects all remaining elements into an array. Rest 参数:将所有剩余元素收集到一个数组中。

 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. Spread operator : allows iterables( arrays / objects / strings ) to be expanded into single arguments/elements.展开运算符:允许将可迭代对象(数组/对象/字符串)扩展为单个参数/元素。

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

Note that the spread operator can be the first element, but the rest parameter needs to be the last to collect the rest elements .请注意,扩展运算符可以是第一个元素,但rest 参数需要是最后一个以收集其余元素。

Basically like in Python:基本上就像在 Python 中一样:

>>> def func(first, *others):
...    return [first, *others]
>>> func('a', 'b', 'c')
['a', 'b', 'c']

Added in ES6 these three dots ... has two meanings, Spread operator and Rest parameter在 ES6 中添加了这三个点...有两个含义,Spread 运算符和 Rest 参数

Spread operator: You use the three dots to expand iterables , by iterables I mean arrays , string , etc. As arguments.展开运算符:您使用三个点来扩展iterablesiterables我的意思是arraysstring等。作为参数。 For example Math.max() function expect an indeterminate number of arguments so you can use Spread operator to expand elements as arguments on Math.max() function.例如Math.max()函数需要不确定数量的参数,因此您可以使用 Spread 运算符将元素扩展为Math.max()函数的参数。 Here an example from mdn这里有一个来自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

Another use case is to add, for example having this array另一个用例是添加,例如拥有这个数组

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

You can add it to another array您可以将其添加到另一个数组

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

Then favoritesVideoGames value is那么favoritesVideoGames值是

[ 'Shadow of the colosus', 'mario galaxy', 'zelda wind waker', 'ico' ]

About Rest parameter, here the MDN definition关于Rest参数,这里是MDN定义

The rest parameter syntax allows us to represent an indefinite number of arguments as an array.其余参数语法允许我们将无限数量的参数表示为一个数组。

This means you can pack many elements into a single element这意味着您可以将许多元素打包成一个元素

Here an example from MDN这里有一个来自 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

I usually get confused with these three points, this illustration by @stephaniecodes helps me to remember its logic.我通常对这三点感到困惑, @stephaniecodes 的这个 插图帮助我记住了它的逻辑。 I mention that I took inspiration from this illustration to answer this question.我提到我从这个插图中获得灵感来回答这个问题。

I hope it is useful.我希望它有用。

In reference to this i cant understand how we are passing a function and returning arguments in javascript关于这一点, 我无法理解我们如何在 javascript 中传递函数并返回参数

Function is a set of instructions that takes some input and processes them and returns result.函数是一组指令,它接受一些输入并处理它们并返回结果。

here we have an array [1, 2, 3, 4, 5, 6], and filter function iterates over each element and passes each element to positive functions which returns the number if it is even, else skips it.这里我们有一个数组 [1, 2, 3, 4, 5, 6],过滤器函数迭代每个元素并将每个元素传递给正函数,如果它是偶数则返回数字,否则跳过它。

trace:痕迹:

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

hence the result [2, 4, 6]因此结果 [2, 4, 6]

considering 3 scenarios考虑3种情况

1] without using any operator 1] 不使用任何运算符

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

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

2] with rest operator 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

- we can gather any number of arguments into an array - 我们可以将任意数量的参数收集到一个数组中

3] with spread operator 3] 使用扩展运算符

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

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

another one另一个

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' ]

From: Ved Antani, Stoyan Stefanov Book “Object-Oriented JavaScript - Third Edition.”来自:Ved Antani,Stoyan Stefanov 着作“面向对象的 JavaScript - 第三版”。 :

Rest parameters休息参数

ES6 introduces rest parameters. ES6引入了rest参数。 Rest parameters allow us to send an arbitrary number of parameters to a function in the form of an array.其余参数允许我们以数组的形式向函数发送任意数量的参数。 Rest parameter can only be the last one in the list of parameters, and there can only be one rest parameter. rest参数只能是参数列表中的最后一个,并且只能有一个rest参数。 Putting a rest operator(...) before the last formal parameter indicates that parameter is a rest parameter.在最后一个形参之前放置一个rest operator(...)表示该参数是一个 rest 参数。 The following example shows adding a rest operator before the last formal parameter:以下示例显示在最后一个形参之前添加一个休息运算符:

function sayThings(tone, ...quotes){ 
  console.log(Array.isArray(quotes)); //true 
  console.log(`In ${tone} voice, I say ${quotes}`) 
} 
sayThings("Morgan Freeman","Something serious"," 
 Imploding Universe"," Amen"); 
//In Morgan Freeman voice, I say Something serious,
 Imploding Universe,Amen 

The first parameter passed to the function is received in tone, while the rest of the parameters are received as an array.传递给函数的第一个参数以音调接收,而其余参数作为数组接收。 Variable arguments (var-args) have been part of several other languages and a welcome edition to ES6 .可变参数 (var-args) 已成为其他几种语言的一部分,也是ES6的受欢迎版本。 Rest parameters can replace the slightly controversial arguments variable.其余参数可以替换略有争议的参数变量。 The major difference between rest parameters and the arguments variable is that the rest parameters are real arrays.其余参数和参数变量之间的主要区别在于,其余参数是实数组。 All array methods are available to rest parameters.所有数组方法都可用于剩余参数。

Spread operators点差运算符

A spread operator looks exactly like a rest operator but performs the exact opposite function.扩展运算符看起来与休息运算符完全相同,但执行的功能完全相反。 Spread operators are used while providing arguments while calling a function or defining an array.在调用函数或定义数组时提供参数时使用扩展运算符。 The spread operator takes an array and splits its element into individual variables.展开运算符接受一个数组并将其元素拆分为单个变量。 The following example illustrates how the spread operator provides a much clearer syntax while calling functions that take an array as an argument:以下示例说明了扩展运算符如何在调用将数组作为参数的函数时提供更清晰的语法:

function sumAll(a,b,c){ 
  return a+b+c 
} 
var numbers = [6,7,8] 
//ES5 way of passing array as an argument of a function 
console.log(sumAll.apply(null,numbers)); //21 
//ES6 Spread operator 
console.log(sumAll(...numbers))//21 

Simple to remember ............简单好记…………

if the triple dots (...) are on the left side its Rest paramenter, if the triple dots are on the right side its Spread parameter.如果三个点 (...) 在左侧是其 Rest 参数,如果三个点在右侧是它的 Spread 参数。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM