Asignación por destructuring

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 una SyntaxError. Revisa Jeff Walden's blog post y bug 1146136 para más detalles.

See also

Etiquetas y colaboradores del documento

Etiquetas: 
 Colaboradores en esta página: rvazquezglez
 Última actualización por: rvazquezglez,