diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md index 776feb40c..dc8254f05 100644 --- a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md +++ b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md @@ -1,20 +1,20 @@ -# Rest parameters and spread syntax +# Parámetros Rest y spread syntax -Many JavaScript built-in functions support an arbitrary number of arguments. +Muchas funciones incorporadas de JavaScript admiten una cantidad arbitraria de argumentos. -For instance: +Por ejemplo: -- `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)` -- devuelve el mayor de los argumentos. +- `Object.assign(dest, src1, ..., srcN)` -- copia propiedades desde `src1..N` a `dest`. +- ...y así. -In this chapter we'll learn how to do the same. And also, how to pass arrays to such functions as parameters. +En este capítulo aprenderemos cómo hacer lo mismo. Y también, cómo pasar Arrays a funciones tales como parámetros. -## Rest parameters `...` +## Parámetros rest `...` -A function can be called with any number of arguments, no matter how it is defined. +Se puede llamar a una función con cualquier número de argumentos, sin importar cómo se defina. -Like here: +Como aquí: ```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. +No habrá errores debido a argumentos "excesivos". Pero, por supuesto, en el resultado solo se contarán los dos primeros. -The rest of the parameters can be included in the function definition by using three dots `...` followed by the name of the array that will contain them. The dots literally mean "gather the remaining parameters into an array". +El resto de los parámetros se pueden incluir en la definición de la función utilizando tres puntos `...` seguidos del nombre del array que los contendrá. Los puntos literalmente significan "reunir los parámetros restantes en un Array". -For instance, to gather all arguments into array `args`: +Por ejemplo, para reunir todos los argumentos en el array `args`: ```js run -function sumAll(...args) { // args is the name for the array +function sumAll(...args) { // args es el mismo para el array let sum = 0; for (let arg of args) sum += arg; @@ -43,16 +43,16 @@ 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. +Podemos elegir obtener los primeros parámetros como variables y luego reunir solo el resto. -Here the first two arguments go into variables and the rest go into `titles` array: +Aquí los dos primeros argumentos van a las variables y el resto va el array `titles`: ```js run function showName(firstName, lastName, ...titles) { alert( firstName + ' ' + lastName ); // Julius Caesar - // the rest go into titles array - // i.e. titles = ["Consul", "Imperator"] + // el resto va a el array titles: + // ej: titles = ["Consul", "Imperator"] alert( titles[0] ); // Consul alert( titles[1] ); // Imperator alert( titles.length ); // 2 @@ -61,8 +61,8 @@ 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="Los parámetros rest deben estar al final" +Los parámetros rest recopilan todos los argumentos restantes, por lo que lo siguiente no tiene sentido y causa un error: ```js function f(arg1, ...rest, arg2) { // arg2 after ...rest ?! @@ -70,14 +70,14 @@ function f(arg1, ...rest, arg2) { // arg2 after ...rest ?! } ``` -The `...rest` must always be last. +El parámetro `...rest` siempre debe ser último. ```` -## The "arguments" variable +## La variable "argumentos" -There is also a special array-like object named `arguments` that contains all arguments by their index. +También hay un objeto especial tipo array llamado `arguments` que contiene todos los argumentos por su índice. -For instance: +Por ejemplo: ```js run function showName() { @@ -85,29 +85,29 @@ function showName() { alert( arguments[0] ); alert( arguments[1] ); - // it's iterable + // Es iterable // for(let arg of arguments) alert(arg); } -// shows: 2, Julius, Caesar +// muestra: 2, Julius, Caesar showName("Julius", "Caesar"); -// shows: 1, Ilya, undefined (no second argument) +// muestra: 1, Ilya, undefined (No hay 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. And it still works, we can find it in the old code. +En los viejos tiempos, los *parámetros rest* no existían en el lenguaje, y el uso de `arguments` era la única forma de obtener todos los argumentos de la función. Y aún funciona, podemos encontrarlo en el código anterior. -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. +Pero la desventaja es que aunque los `arguments` son a la vez como un Array e iterables, no es un Array. No admite métodos Array, por lo que no podemos llamar a `arguments.map(...)`. -Also, it always contains all arguments. We can't capture them partially, like we did with rest parameters. +Además, siempre contiene todos los argumentos. No podemos capturarlos parcialmente, como hicimos con los parámetros rest. -So when we need these features, then rest parameters are preferred. +Entonces, cuando necesitamos estas características, se prefieren los parámetros rest. ````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. +Si accedemos al objeto `arguments` desde una arrow function, los toma desde la función "normal" externa. -Here's an example: +Aquí hay un ejemplo: ```js run function f() { @@ -118,25 +118,25 @@ function f() { 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 recordamos, las arrow functions no tienen su propio `this`. Ahora sabemos que tampoco tienen el objeto especial `arguments`. ```` ## Spread syntax [#spread-syntax] -We've just seen how to get an array from the list of parameters. +Acabamos de ver cómo obtener un Array de la lista de parámetros. -But sometimes we need to do exactly the reverse. +Pero a veces necesitamos hacer exactamente lo contrario. -For instance, there's a built-in function [Math.max](mdn:js/Math/max) that returns the greatest number from a list: +Por ejemplo, hay una función incorporada [Math.max](mdn:js/Math/max) que devuelve el mayor número de una lista: ```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? +Ahora digamos que tenemos Array `[3, 5, 1]`. ¿Cómo llamamos a `Math.max` con él? -Passing it "as is" won't work, because `Math.max` expects a list of numeric arguments, not a single array: +Pasarlo "como está" no funcionará, porque `Math.max` espera una lista de argumentos numéricos, no un solo Array: ```js run let arr = [3, 5, 1]; @@ -146,21 +146,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. +Y seguramente no podemos enumerar manualmente los elementos en el código `Math.max(arr [0], arr [1], arr [2])`, porque podemos no estar seguros de cuántos hay. A medida que se ejecuta nuestro script, podrían haber muchos o no podría haber ninguno. Y eso se pondría feo. -*Spread syntax* to the rescue! It looks similar to rest parameters, also using `...`, but does quite the opposite. +*Spread syntax* al rescate! Se ve similar a los parámetros rest, también usando `...`, pero hace todo lo contrario. -When `...arr` is used in the function call, it "expands" an iterable object `arr` into the list of arguments. +Cuando se usa `... arr` en la llamada a la función, "expande" un objeto iterable `arr` en la lista 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 convierte el Array en una lista de argumentos) ``` -We also can pass multiple iterables this way: +También podemos pasar múltiples iterables de esta manera: ```js run let arr1 = [1, -2, 3, 4]; @@ -169,7 +169,7 @@ let arr2 = [8, 3, -8, 1]; alert( Math.max(...arr1, ...arr2) ); // 8 ``` -We can even combine the spread syntax with normal values: +Incluso podemos combinar spread syntax con valores normales: ```js run @@ -179,7 +179,7 @@ let arr2 = [8, 3, -8, 1]; alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25 ``` -Also, the spread syntax can be used to merge arrays: +Además, spread syntax se puede utilizar para fusionar Arrays: ```js run let arr = [3, 5, 1]; @@ -189,12 +189,12 @@ 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, luego arr, luego 2, luego arr2) ``` -In the examples above we used an array to demonstrate the spread syntax, but any iterable will do. +En los ejemplos anteriores, utilizamos un Array para demostrar spread syntax, pero cualquier iterable funcionará. -For instance, here we use the spread syntax to turn the string into array of characters: +Por ejemplo, aquí usamos spread syntax para convertir la cadena en un Array de caracteres: ```js run let str = "Hello"; @@ -202,88 +202,88 @@ let str = "Hello"; alert( [...str] ); // H,e,l,l,o ``` -The spread syntax internally uses iterators to gather elements, the same way as `for..of` does. +Spread syntax utiliza internamente iteradores para reunir elementos, de la misma manera que lo hace `for..of`. -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]`. +Entonces, para un string, `for..of` devuelve caracteres y `...str` se convierte en `"H","e","l","l","o"`. La lista de caracteres se pasa al inicializador de array `[...str]`. -For this particular task we could also use `Array.from`, because it converts an iterable (like a string) into an array: +Para esta tarea en particular también podríamos usar `Array.from`, porque convierte un iterable (como un string) en un Array: ```js run let str = "Hello"; -// Array.from converts an iterable into an array +// Array.from convierte un iterable en un array alert( Array.from(str) ); // H,e,l,l,o ``` -The result is the same as `[...str]`. +El resultado es el mismo que `[...str]`. -But there's a subtle difference between `Array.from(obj)` and `[...obj]`: +Pero hay una sutil diferencia entre `Array.from(obj)` y `[...obj]`: -- `Array.from` operates on both array-likes and iterables. -- The spread syntax works only with iterables. +- `Array.from` opera en ambos, arrays e iterables +- El spread syntax solo funciona con iterables. -So, for the task of turning something into an array, `Array.from` tends to be more universal. +Entonces, para la tarea de convertir algo en un array, `Array.from` tiende a ser más universal. +## Obtener una nueva copia de un objeto/array -## Get a new copy of an array/object +Recuerdas cuando hablamos sobre `Object.assign()` [en el pasado](https://javascript.info/object#cloning-and-merging-object-assign)? -Remember when we talked about `Object.assign()` [in the past](https://javascript.info/object#cloning-and-merging-object-assign)? +¡Es posible hacer lo mismo con el operador spread! -It is possible to do the same thing with the spread syntax. ```js run let arr = [1, 2, 3]; -let arrCopy = [...arr]; // spread the array into a list of parameters - // then put the result into a new array +let arrCopy = [...arr]; // difunde el array en una lista de parámetros + // luego coloca el resultado en un nuevo array -// do the arrays have the same contents? +// ¿Los Arrays tienen el mismo contenido? alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true -// are the arrays equal? -alert(arr === arrCopy); // false (not same reference) +// ¿Los arrays son iguales? +alert(arr === arrCopy); // false (no es la misma referencia) -// modifying our initial array does not modify the copy: +// Modificar nuestro array inicial no modifica la copia: arr.push(4); alert(arr); // 1, 2, 3, 4 alert(arrCopy); // 1, 2, 3 ``` -Note that it is possible to do the same thing to make a copy of an object: +Tenga en cuenta que es posible hacer lo mismo para hacer una copia de un objeto: ```js run let obj = { a: 1, b: 2, c: 3 }; -let objCopy = { ...obj }; // spread the object into a list of parameters - // then return the result in a new object +let objCopy = { ...obj }; // difunde el array en una lista de parámetros + // luego coloca el resultado en un nuevo array -// do the objects have the same contents? +// ¿Los objetos tienen el mismo contenido? alert(JSON.stringify(obj) === JSON.stringify(objCopy)); // true -// are the objects equal? -alert(obj === objCopy); // false (not same reference) +// ¿Son iguales los objetos? +alert(obj === objCopy); // false (no es la misma referencia) -// modifying our initial object does not modify the copy: +// La modificación de nuestro objeto inicial no modifica la copia: obj.d = 4; alert(JSON.stringify(obj)); // {"a":1,"b":2,"c":3,"d":4} alert(JSON.stringify(objCopy)); // {"a":1,"b":2,"c":3} ``` -This way of copying an object is much shorter than `let objCopy = Object.assign({}, obj);` or for an array `let arrCopy = Object.assign([], arr);` so we prefer to use it whenever we can. +Esta forma de copiar un objeto es mucho más corta que `let objCopy = Object.assign({}, obj);` o para un array `let arrCopy = Object.assign ([], arr);` por lo que preferimos usarlo siempre que podamos. -## Summary +## Resumen -When we see `"..."` in the code, it is either rest parameters or the spread syntax. +Cuando vemos `" ... "` en el código, se trata de parámetros rest o de spread syntax. -There's an easy way to distinguish between them: +Hay una manera fácil de distinguirlos: -- 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 syntax" and expands an array into a list. +- Cuando `...` está al final de los parámetros de la función, se trata de "parámetros rest" y reúne el resto de la lista de argumentos en un array. +- Cuando `...` ocurre en una llamada de función o similar, se llama "spread syntax" y expande un array en una lista. -Use patterns: +Usar patrones: -- Rest parameters are used to create functions that accept any number of arguments. -- The spread syntax is used to pass an array to functions that normally require a list of many arguments. +- Parámetros rest se utilizan para crear funciones que aceptan cualquier número de argumentos. +- Spread syntax se utiliza para pasar un array a funciones que normalmente requieren una lista de muchos argumentos. -Together they help to travel between a list and an array of parameters with ease. +Juntos ayudan a viajar entre una lista y una variedad de parámetros con facilidad. -All arguments of a function call are also available in "old-style" `arguments`: array-like iterable object. +Todos los argumentos de una llamada a función también están disponibles en el "viejo estilo" `arguments`: objeto iterable tipo array.