Este articulo necesita una revisión técnica. Cómo puedes ayudar.
Este articulo necesita una revisión editorial. Cómo puedes ayudar.
Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.
This is a new technology, part of the ECMAScript 2015 (ES6) standard.
This technology's specification has been finalized, but check the compatibility table for usage and implementation status in various browsers.
La sintaxis de destructuring assignment es una expresión de JavaScript que hace posible la extracción de datos de arreglos u objetos usando una sintaxis que equivale a la construcción de arreglos y objetos literales.
Sintaxis
[a, b] = [1, 2] [a, b, ...rest] = [1, 2, 3, 4, 5] {a, b} = {a:1, b:2} {a, b, ...rest} = {a:1, b:2, c:3, d:4} //ES7
{a, b} = {a:1, b:2}
por si solo no es valido en la sintaxix, ya que {a, b}
del lado izquierdo es considerado un bloque y no un objeto literal.
Sin embargo, la forma ({a, b} = {a:1, b:2})
es válida, así como la forma var {a, b} = {a:1, b:2}
.
Descripción
Las expresiones literales de objetos y arreglos proporcionan una forma sencilla de crear paquetes de datos ad hoc. Una vez que dispones de estos paquetes de datos, puedes usarlos de cualquier forma. Incluso puedes regresarlos de funciones.
Algo particularmente útil que puedes hacer con destructuring assignment es leer una estructura completa en una sola sentencia, aunque también hay un monton de cosas interesantes que puedes hacer, como se muestra en los siguientes ejemplos.
Esta capacidad es similar a funcionalidades que puedes encontrar en otros lenguajes como Perl y Python.
Array destructuring
Ejemplo sencillo
var foo = ["uno", "dos", "tres"]; // sin destructuring var uno = foo[0]; var dos = foo[1]; var tres = foo[2]; // asignación en tres lineas // con destructuring var [uno, dos, tres] = foo; // asignación en una sola linea
Asignación sin declaración
Destructuring assignment puede ser usado sin necesida de declarar en la sentencia de asignación.
var a, b; [a, b] = [1, 2];
Cambiando orden de las variables
Después de ejecutar este código, b es 1 y a es 3. Sin destructuring assignment, cambiar el orden de dos variables requiere una variable temporal (alternativamente en algunos lenguajes de bajo nivel se puede usar el algoritmo XOR-swap).
var a = 1; var b = 3; [a, b] = [b, a];
Multiples valores de retorno
Gracias a destructuring assignment, las funciones pueden retornar multiples valores. Aunque en JavaScript siempre ha sido posible regresar un arreglo de una función, esto agrega más flexibilidad.
function f() { return [1, 2]; }
Como puedes ver, se pueden regresar resultados usando notación de arreglo, con los valores a regresar encerrados en corchetes. De esta forma puedes regresar cualquier número de resultados. En el siguiente ejemplo, f()
regresa los valores [1, 2]
como resultado.
var a, b; [a, b] = f(); console.log("A es " + a + " B es " + b);
La sentencia [a, b] = f()
assigna los resultados de las variables en corchetes en orden: a a se le asigna el valor de 1 y a b se le asigna 2.
También puedes tomar los valores de retorno en un arreglo:
var a = f(); console.log("A es " + a);
En este caso, a es un arreglo que contiene los valores 1 y 2.
Ignorando algunos valores de retorno
Puedes ignorar los valores de retorno en los que no estás interesado:
function f() { return [1, 2, 3]; } var [a, , b] = f(); console.log("A es " + a + " B es " + b);
Después de correr este código a vale 1 y b vale 3. El valor 2 es ignorado. Puedes ignorar cualquiera de los valores retornados (o incluso todos). Por ejemplo:
[,,] = f();
Pulling values from a regular expression match
When the regular expression exec()
method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to pull the parts out of this array easily, ignoring the full match if it is not needed.
var url = "https://developer.mozilla.org/en-US/Web/JavaScript"; var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url); var [, protocol, fullhost, fullpath] = parsedURL; console.log(protocol); // logs "https:"
Object destructuring
Ejemplo sencillo
var o = {p: 42, q: true}; var {p, q} = o; console.log(p); // 42 console.log(q); // true // Asigna nuevos nombres de variable var {p: foo, q: bar} = o; console.log(foo); // 42 console.log(bar); // true
Asignación sin declaración
Se puede hacer destructuring assignment sin declaración en la sentencia de asignación.
var a, b; ({a, b} = {a:1, b:2});
Los paréntesis ( .. )
que cubren la sentencia de asignación se requieren cuando se usa asignación object literal destructuring sin una declaración.
Argumentos por default en funciones
Version de ES5
function drawES5Chart(options) { options = options === undefined ? {} : options; var size = options.size === undefined ? 'big' : options.size; var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords; var radius = options.radius === undefined ? 25 : options.radius; console.log(size, cords, radius); // now finally do some chart drawing } drawES5Chart({ cords: { x: 18, y: 30 }, radius: 30 });
Version de ES6
function drawES6Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) { console.log(size, cords, radius); // do some chart drawing } drawES6Chart({ cords: { x: 18, y: 30 }, radius: 30 });
En Firefox, todavía no se implementan los valores por default en destructuring assignments : var { x = 3 } = {} and var [foo = "bar"] = []. Revisa bug 932080 para valores destructured por default en funciones.
Carga de módulos (no-ES6)
Destructuring puede ser útil para carga de subconjuntos específicos de módulos no-ES6 como aquí en Add-on SDK:
const { Loader, main } = require('toolkit/loader');
Objetos anidados y destructuring de arreglos
var metadata = { title: "Scratchpad", translations: [ { locale: "de", localization_tags: [ ], last_edit: "2014-04-14T08:43:37", url: "/de/docs/Tools/Scratchpad", title: "JavaScript-Umgebung" } ], url: "/en-US/docs/Tools/Scratchpad" }; var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata; console.log(englishTitle); // "Scratchpad" console.log(localeTitle); // "JavaScript-Umgebung"
For para iteraciones con destructuring
var people = [ { name: "Mike Smith", family: { mother: "Jane Smith", father: "Harry Smith", sister: "Samantha Smith" }, age: 35 }, { name: "Tom Jones", family: { mother: "Norah Jones", father: "Richard Jones", brother: "Howard Jones" }, age: 25 } ]; for (var {name: n, family: { father: f } } of people) { console.log("Name: " + n + ", Father: " + f); } // "Name: Mike Smith, Father: Harry Smith" // "Name: Tom Jones, Father: Richard Jones"
Obteniendo campos de objetos pasados como parametros de función
function userId({id}) { return id; } function whois({displayName: displayName, fullName: {firstName: name}}){ console.log(displayName + " is " + name); } var user = { id: 42, displayName: "jdoe", fullName: { firstName: "John", lastName: "Doe" } }; console.log("userId: " + userId(user)); // "userId: 42" whois(user); // "jdoe is John"
Esto obtiene los campos id
, displayName
and firstName
del objeto usuario e imprime los valores.
Computed object property names and destructuring
Computed property names, like on object literals, can be used with destructuring.
let key = "z"; let { [key]: foo } = { z: "bar" }; console.log(foo); // "bar"
Específicaciones
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Destructuring assignment' in that specification. |
Standard | Initial definition. |
Compatibilidad en navegadores
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | Not supported | 2.0 (1.8.1) | Not supported | Not supported | 7.1 |
Computed property names | Not supported | 34 (34) | Not supported | Not supported | Not supported |
Spread operator | ? | 34 (34) | ? | ? | ? |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | Not supported | Not supported | 1.0 (1.0) | Not supported | Not supported | 8 |
Computed property names | Not supported | Not supported | 34.0 (34) | Not supported | Not supported | Not supported |
Spread operator | ? | ? | 34.0 (34) | ? | ? | ? |
Notas específicas para Firefox
- Firefox proporciona una extensión no estándar del lenguaje para destructuring en JS1.7. Esta extensión se quitó de Gecko 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37). Puedes revisar bug 1083498.
- A partir de Gecko 41 (Firefox 41 / Thunderbird 41 / SeaMonkey 2.38) y para cumplir con la especificación ES6, los patrones de destructuring con paréntesis, como
([a, b]) = [1, 2]
or({a, b}) = { a: 1, b: 2 }
, ahora se consideran inválidos y lanzan unaSyntaxError
. Revisa Jeff Walden's blog post y bug 1146136 para más detalles.