diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md index a98d8eddd..34a64333f 100644 --- a/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md +++ b/1-js/06-advanced-functions/02-rest-parameters-spread-operator/article.md @@ -1,20 +1,20 @@ -# Rest parameters and spread operator +# Parâmetros _rest_ e operador _spread_ -Many JavaScript built-in functions support an arbitrary number of arguments. +Várias funções embutidas no JavaScript suportam um número arbitrário de argumentos. -For instance: +Por exemplo: -- `Math.max(arg1, arg2, ..., argN)` -- returns the greatest of the arguments. -- `Object.assign(dest, src1, ..., srcN)` -- copies properties from `src1..N` into `dest`. -- ...and so on. +- `Math.max(arg1, arg2, ..., argN)` -- retorna o maior dos argumentos. +- `Object.assign(dest, src1, ..., srcN)` -- copia propriedades de `src1..N` para `dest`. +- ...e assim por diante. -In this chapter we'll learn how to do the same. And, more importantly, how to feel comfortable working with such functions and arrays. +Neste capítulo vamos aprender a fazer o mesmo e, o mais importante, se sentindo confortável trabalhando com tais funções e listas (_arrays_). -## Rest parameters `...` +## Parâmetros _rest_ `...` -A function can be called with any number of arguments, no matter how it is defined. +Uma função pode ser chamada com qualquer número de argumentos, não importa a sua definição. -Like here: +Como por exemplo: ```js run function sum(a, b) { return a + b; @@ -23,14 +23,14 @@ function sum(a, b) { alert( sum(1, 2, 3, 4, 5) ); ``` -There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted. +Não haverão erros por "uso excessivo" de argumentos, mas é claro que somente os dois primeiros valores serão levados em consideração no resultado. -The rest parameters can be mentioned in a function definition with three dots `...`. They literally mean "gather the remaining parameters into an array". +Os parâmetros _rest_, podem ser declarados na definição da função com três pontos `...`. Eles literalmente significam "reúna os parâmetros restantes em uma lista (_array_)". -For instance, to gather all arguments into array `args`: +Por exemplo, para reunir todos os argumentos em um _array_ `args`: ```js run -function sumAll(...args) { // args is the name for the array +function sumAll(...args) { // args é o nome do 'array' let sum = 0; for (let arg of args) sum += arg; @@ -43,15 +43,15 @@ alert( sumAll(1, 2) ); // 3 alert( sumAll(1, 2, 3) ); // 6 ``` -We can choose to get the first parameters as variables, and gather only the rest. +Nós podemos escolher receber os primeiros parâmetros como variáveis, e reunir os restantes. -Here the first two arguments go into variables and the rest go into `titles` array: +Abaixo os primeiros dois argumentos vão para variáveis, e os restantes para o _array_ `titles`: ```js run function showName(firstName, lastName, ...titles) { alert( firstName + ' ' + lastName ); // Julius Caesar - // the rest go into titles array + // o restante vai para o array titles // i.e. titles = ["Consul", "Imperator"] alert( titles[0] ); // Consul alert( titles[1] ); // Imperator @@ -61,23 +61,23 @@ function showName(firstName, lastName, ...titles) { showName("Julius", "Caesar", "Consul", "Imperator"); ``` -````warn header="The rest parameters must be at the end" -The rest parameters gather all remaining arguments, so the following does not make sense and causes an error: +````warn header="Os parâmetros rest devem estar no final" +Os parâmetros _rest_ reúnem todos os argumentos restantes, então o exemplo seguinte não faz sentido e causa um erro: ```js -function f(arg1, ...rest, arg2) { // arg2 after ...rest ?! - // error +function f(arg1, ...rest, arg2) { // arg2 depois de ...rest ?! + // erro } ``` -The `...rest` must always be last. +O `...rest` deve estar sempre no final. ```` -## The "arguments" variable +## A variável "arguments" -There is also a special array-like object named `arguments` that contains all arguments by their index. +Há também, um tipo especial de objeto com caracteristicas de listas (_array-like_, ou lista genérica), chamado de arguments que contém todos os argumentos segundo a ordem dos seus índices. -For instance: +Por exemplo: ```js run function showName() { @@ -85,31 +85,31 @@ function showName() { alert( arguments[0] ); alert( arguments[1] ); - // it's iterable + // é iterável // for(let arg of arguments) alert(arg); } -// shows: 2, Julius, Caesar +// exibe: 2, Julius, Caesar showName("Julius", "Caesar"); -// shows: 1, Ilya, undefined (no second argument) +// exibe: 1, Ilya, undefined (não possui um segundo argumento) showName("Ilya"); ``` -In old times, rest parameters did not exist in the language, and using `arguments` was the only way to get all arguments of the function, no matter their total number. +Antigamente, parâmetros _rest_ não existiam na linguagem, portanto usar `arguments` era a única forma de receber todos os argumentos da função, não importando o total dos seus argumentos. -And it still works, we can use it today. +E isso ainda funciona atualmente. -But the downside is that although `arguments` is both array-like and iterable, it's not an array. It does not support array methods, so we can't call `arguments.map(...)` for example. +Mas a desvantagem é que, apesar do `arguments` ter algumas caracteristicas de _arrays_ e de ser iterável, não é um _array_ de fato. Ele não suporta métodos de _arrays_, por exemplo, não podemos chamar `arguments.map(...)`. -Also, it always contains all arguments. We can't capture them partially, like we did with rest parameters. +E além disso, sempre contém todos os argumentos. Não podemos os obter parcialmente, como o fizemos com parâmetros _rest_. -So when we need these features, then rest parameters are preferred. +Então, quando precisamos dessas funcionalidades, os parâmetros _rest_ são a preferência. -````smart header="Arrow functions do not have `\"arguments\"`" -If we access the `arguments` object from an arrow function, it takes them from the outer "normal" function. +````smart header="Funções arrow não possuem `\"arguments\"`" +Se tentarmos acessar o objeto `arguments` de dentro de uma função _arrow_, ele os recebe da função "normal" externa. -Here's an example: +Aqui está um exemplo: ```js run function f() { @@ -121,23 +121,23 @@ f(1); // 1 ``` ```` -As we remember, arrow functions don't have their own `this`. Now we know they don't have the special `arguments` object either. +Como nos lembramos, funções _arrow_ não possuem o seu próprio `this`. Agora, sabemos que elas também não possuem o especial `arguments`. -## Spread operator [#spread-operator] +## Operador _spread_ [_spread-operator_] -We've just seen how to get an array from the list of parameters. +Acabamos de ver como obter um _array_ de uma lista simples de parâmetros (apenas lista em sequência, não _array_). -But sometimes we need to do exactly the reverse. +Mas às vezes precisamos fazer exatamente o oposto. -For instance, there's a built-in function [Math.max](mdn:js/Math/max) that returns the greatest number from a list: +Por exemplo, existe uma função embutida [Math.max](mdn:js/Math/max) que retorna o maior número de uma lista simples (não _array_): ```js run alert( Math.max(3, 5, 1) ); // 5 ``` -Now let's say we have an array `[3, 5, 1]`. How do we call `Math.max` with it? +Agora vamos dizer que temos um _array_ `[3, 5, 1]`. Como podemos fazer para chamar `Math.max` com ele? -Passing it "as is" won't work, because `Math.max` expects a list of numeric arguments, not a single array: +Passar o _array_ "como ele é" não irá funcionar porque, `Math.max` espera uma lista simples de argumentos numéricos, não num todo num _array_. ```js run let arr = [3, 5, 1]; @@ -147,21 +147,21 @@ alert( Math.max(arr) ); // NaN */!* ``` -And surely we can't manually list items in the code `Math.max(arr[0], arr[1], arr[2])`, because we may be unsure how many there are. As our script executes, there could be a lot, or there could be none. And that would get ugly. +E certamente, não podemos listar os itens manualmente no código `Math.max(arr[0], arr[1], arr[2])` porque podemos não a ter certeza de quantos argumentos são. Conforme nosso script é executado, podem haver muitos parâmetros ou pode não haver nenhum. E isso ficaria muito feio. -*Spread operator* to the rescue! It looks similar to rest parameters, also using `...`, but does quite the opposite. +O *operador spread* vem para nos salvar! Ele é bem similar ao parâmetro _rest_, também usando `...`, mas faz o contrário. -When `...arr` is used in the function call, it "expands" an iterable object `arr` into the list of arguments. +Quando `...arr` é usado em uma chamada de função, ele "expande" um objeto iterável `arr` em uma lista simples de argumentos. -For `Math.max`: +Para `Math.max`: ```js run let arr = [3, 5, 1]; -alert( Math.max(...arr) ); // 5 (spread turns array into a list of arguments) +alert( Math.max(...arr) ); // 5 (spread transforma um array em uma lista de argumentos) ``` -We also can pass multiple iterables this way: +Também podemos passar múltiplos iteráveis da seguinte forma: ```js run let arr1 = [1, -2, 3, 4]; @@ -170,8 +170,7 @@ let arr2 = [8, 3, -8, 1]; alert( Math.max(...arr1, ...arr2) ); // 8 ``` -We can even combine the spread operator with normal values: - +Podemos até combinar o operador spread com valores normais: ```js run let arr1 = [1, -2, 3, 4]; @@ -180,7 +179,7 @@ let arr2 = [8, 3, -8, 1]; alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25 ``` -Also, the spread operator can be used to merge arrays: +Além disso, o operador spread também pode ser usado para juntar valores individuais de _arrays_: ```js run let arr = [3, 5, 1]; @@ -190,56 +189,55 @@ let arr2 = [8, 9, 15]; let merged = [0, ...arr, 2, ...arr2]; */!* -alert(merged); // 0,3,5,1,2,8,9,15 (0, then arr, then 2, then arr2) +alert(merged); // 0,3,5,1,2,8,9,15 (0, depois arr, depois 2, depois arr2) ``` -In the examples above we used an array to demonstrate the spread operator, but any iterable will do. +Nos exemplos acima usamos um _array_ para demonstrar o operador _spread_, mas qualquer iterável também funcionaria. -For instance, here we use the spread operator to turn the string into array of characters: +Por exemplo, aqui usamos o operador _spread_ para transformar uma string em um _array_ de caracteres: ```js run -let str = "Hello"; +let str = "Olá"; -alert( [...str] ); // H,e,l,l,o +alert( [...str] ); // O,l,á ``` -The spread operator internally uses iterators to gather elements, the same way as `for..of` does. +Internamente, o operador _spread_ usa iteradores (_iterators_) para reunir elementos, da mesma forma como `for..of` faz. -So, for a string, `for..of` returns characters and `...str` becomes `"H","e","l","l","o"`. The list of characters is passed to array initializer `[...str]`. +Então, para uma string, `for..of` retorna caracteres, e `...str` se torna `"O","l","á"`. A lista de caracteres é passada para o inicializador do _array_ `[...str]` -For this particular task we could also use `Array.from`, because it converts an iterable (like a string) into an array: +Para essa tarefa em particular nós também poderíamos usar `Array.from`, porque ele converte um iterável (como uma string) em um _array_. ```js run -let str = "Hello"; +let str = "Olá"; -// Array.from converts an iterable into an array -alert( Array.from(str) ); // H,e,l,l,o +// Array.from converte um interável em um _array_ +alert( Array.from(str) ); // O,l,á ``` -The result is the same as `[...str]`. - -But there's a subtle difference between `Array.from(obj)` and `[...obj]`: +O resultado é o mesmo que `...[str]`. -- `Array.from` operates on both array-likes and iterables. -- The spread operator operates only on iterables. +Mas há uma diferença sútil entre `Array.from(obj)` e `[...obj]`: -So, for the task of turning something into an array, `Array.from` tends to be more universal. +- `Array.from` opera tanto em listas-genéricas (_array-likes_) como em iteráveis. +- O operador _spread_ opera somente em iteráveis. +Então, para a tarefa de transformar algo em um _array_, `Array.from` tende a ser uma solução mais universal. -## Summary +## Sumário -When we see `"..."` in the code, it is either rest parameters or the spread operator. +Quando nos depararmos com `"..."` no código, estamos falando de parâmetros _rest_ ou do operador _spread_. -There's an easy way to distinguish between them: +Existe uma forma fácil para distinguir entre eles: -- When `...` is at the end of function parameters, it's "rest parameters" and gathers the rest of the list of arguments into an array. -- When `...` occurs in a function call or alike, it's called a "spread operator" and expands an array into a list. +- Quando `...` está no final dos parâmetros da função, é "parâmetros _rest_" e reune o restante da lista de argumentos em um _array_. +- Quando `...` ocorre em uma chamada de função ou similar, é chamado de "operador _spread_" e expande um _array_ em uma lista. -Use patterns: +Padrões de uso: -- 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. +- Operadores _rest_ são usados para criar funções que aceitem qualquer número de argumentos. +- O operador _spread_ é usado para passar um _array_ em funções que normalmente requerem uma lista de muitos argumentos. -Together they help to travel between a list and an array of parameters with ease. +Juntos, eles nos ajudam a efetuar a transição entre uma lista e um _array_ de parâmetros com facilidade. -All arguments of a function call are also available in "old-style" `arguments`: array-like iterable object. +Todos os argumentos de uma chamada de função também estão disponíveis na "moda antiga" `arguments`: objeto iterável do tipo lista-genérica (_array-like_).