La desestructuraci贸n

La sintaxis de desestructuraci贸n es una expresi贸n de JavaScript que permite desempacar valores de arreglos o propiedades de objetos en distintas variables.

Sintaxis

let a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({ a, b } = { a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20


// Propuesta de etapa 4 (terminada)
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}

Descripci贸n

Las expresiones de objetos y arreglos literales proporcionan una manera f谩cil de crear paquetes de datos ad hoc.

const x = [1, 2, 3, 4, 5];

La desestructuraci贸n utiliza una sintaxis similar, pero en el lado izquierdo de la asignaci贸n para definir qu茅 valores desempacar de la variable origen.

const x = [1, 2, 3, 4, 5];
const [y, z] = x;
console.log(y); // 1
console.log(z); // 2

Esta capacidad es similar a las caracter铆sticas presentes en lenguajes como Perl y Python.

Ejemplos

Desestructuraci贸n de arreglos

Asignaci贸n b谩sica de variables

const foo = ['one', 'two', 'three'];

const [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"

Asignaci贸n separada de la declaraci贸n

A una variable se le puede asignar su valor mediante una desestructuraci贸n separada de la declaraci贸n de la variable.

let a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

Valores predeterminados

A una variable se le puede asignar un valor predeterminado, en el caso de que el valor desempacado del arreglo sea undefined.

let a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

Intercambio de variables

Los valores de dos variables se pueden intercambiar en una expresi贸n de desestructuraci贸n.

Sin desestructurar la asignaci贸n, intercambiar dos valores requiere una variable temporal (o, en algunos lenguajes de bajo nivel, el algoritmo del truco XOR-swap).

let a = 1;
let b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

const arr = [1,2,3];
[arr[2], arr[1]] = [arr[1], arr[2]];
console.log(arr); // [1,3,2]

Analizar un arreglo devuelto por una funci贸n

Siempre ha sido posible devolver un arreglo desde una funci贸n. La desestructuraci贸n puede hacer que trabajar con un valor de retorno de arreglo sea m谩s conciso.

En este ejemplo, f() devuelve los valores [1, 2] como su salida, que se puede procesar en una sola l铆nea con desestructuraci贸n.

function f() {
  return [1, 2];
}

let a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2

Ignorar algunos valores devueltos

Puedes ignorar los valores de retorno que no te interesan:

function f() {
  return [1, 2, 3];
}

const [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

const [c] = f();
console.log(c); // 1

Tambi茅n puedes ignorar todos los valores devueltos:

[,,] = f();

Asignar el resto de un arreglo a una variable

Al desestructurar un arreglo, puedes desempacar y asignar la parte restante a una variable usando el patr贸n resto:

const [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]

Ten en cuenta que se lanzar谩 un SyntaxError si se usa una coma final en el lado derecho con un elemento resto:

const [a, ...b,] = [1, 2, 3];

// SyntaxError: el elemento rest no puede tener una coma al final
// Siempre considera usar el operador rest como 煤ltimo elemento

Desempacar valores coincidentes con una expresi贸n regular

Cuando el m茅todo de expresi贸n regular exec() encuentra una coincidencia, devuelve un arreglo que contiene primero toda la parte coincidente de la cadena y luego las partes de la cadena que coinciden con cada grupo entre par茅ntesis en la expresi贸n regular. La desestructuraci贸n te permite desempacar f谩cilmente las partes de este arreglo, ignorando la coincidencia completa si no es necesaria.

function parseProtocol(url) {
  const parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
  if (!parsedURL) {
    return false;
  }
  console.log(parsedURL);
  // ["https://developer.mozilla.org/es/Web/JavaScript",
      "https", "developer.mozilla.org", "es/Web/JavaScript"]

  const [, protocol, fullhost, fullpath] = parsedURL;
  return protocol;
}

console.log(parseProtocol('https://developer.mozilla.org/es/Web/JavaScript'));
// "https"

Desestructuraci贸n de objetos

Asignaci贸n b谩sica

const user = {
    id: 42,
    is_verified: true
};

const {id, is_verified} = user;

console.log(id); // 42
console.log(is_verified); // true

Asignaci贸n sin declaraci贸n

A una variable se le puede asignar su valor con desestructuraci贸n separada de su declaraci贸n.

let a, b;

({a, b} = {a: 1, b: 2});

Notas: los par茅ntesis (...) alrededor de la declaraci贸n de asignaci贸n son obligatorios cuando se usa la desestructuraci贸n de un objeto literal sin una declaraci贸n.

{a, b} = {a: 1, b: 2} no es una sintaxis independiente v谩lida, debido a que {a, b} en el lado izquierdo se considera un bloque y no un objeto literal.

Sin embargo, ({a, b} = {a: 1, b: 2}) es v谩lido, al igual que const {a, b} = {a: 1, b: 2}

tu expresi贸n ( ... ) debe estar precedida por un punto y coma o se puede usar para ejecutar una funci贸n en la l铆nea anterior.

Asignar a nuevos nombres de variable

Una propiedad se puede desempacar de un objeto y asignar a una variable con un nombre diferente al de la propiedad del objeto.

const o = {p: 42, q: true};
const {p: foo, q: bar} = o;

console.log(foo); // 42
console.log(bar); // true

Aqu铆, por ejemplo, const {p: foo} = o toma del objeto o la propiedad llamada p y la asigna a una variable local llamada foo.

Valores predeterminados

A una variable se le puede asignar un valor predeterminado, en el caso de que el valor desempacado del objeto sea undefined.

const {a = 10, b = 5} = {a: 3};

console.log(a); // 3
console.log(b); // 5

Asignar nombres a nuevas variables y proporcionar valores predeterminados

Una propiedad puede ser ambas

  • Desempacada de un objeto y asignada a una variable con un nombre diferente.
  • Se le asigna un valor predeterminado en caso de que el valor desempacado sea undefined.
const {a: aa = 10, b: bb = 5} = {a: 3};

console.log(aa); // 3
console.log(bb); // 5

Desempacar campos de objetos pasados como par谩metro de funci贸n

const user = {
  id: 42,
  displayName: 'jdoe',
  fullName: {
    firstName: 'John',
    lastName: 'Doe'
  }
};

function userId({id}) {
  return id;
}

function whois({displayName, fullName: {firstName: name}}) {
  return `${displayName} es ${name}`;
}

console.log(userId(user)); // 42
console.log(whois(user));  // "jdoe es John"

Esto desempaca el id, displayName y firstName del objeto user y los imprime.

Establecer el valor predeterminado de un par谩metro de funci贸n

function drawChart({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}) {
  console.log(size, coords, radius);
  // haz un dibujo de gr谩fico
}

drawChart({
  coords: {x: 18, y: 30},
  radius: 30
});

En la firma de la funci贸n para drawChart anterior, el lado izquierdo desestructurado se asigna a un objeto literal vac铆o en el lado derecho: {size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}. Tambi茅n podr铆as haber escrito la funci贸n sin la asignaci贸n del lado derecho. Sin embargo, si omites la asignaci贸n del lado derecho, la funci贸n buscar谩 al menos un argumento para ser proporcionado cuando se invoca, mientras que en su forma actual, simplemente puedes llamar a drawChart() sin proporcionar ning煤n par谩metro. El dise帽o actual es 煤til si deseas poder llamar a la funci贸n sin proporcionar ning煤n par谩metro, el otro puede ser 煤til cuando deseas asegurarte de que se pase un objeto a la funci贸n.

Desestructuraci贸n de arreglos y objetos anidados

const metadata = {
  title: 'Scratchpad',
  translations: [
    {
      locale: 'de',
      localization_tags: [],
      last_edit: '2020-08-29T08:43:37',
      url: '/de/docs/Tools/Scratchpad',
      title: 'JavaScript-Umgebung'
    }
  ],
  url: '/es/docs/Tools/Scratchpad'
};

let {
  title: englishTitle, // renombrar
  translations: [
    {
       title: localeTitle, // renombrar
    },
  ],
} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle);  // "JavaScript-Umgebung"

Iteraci贸n "for...of" y desestructuraci贸n

const 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 (const {name: n, family: {father: f}} of people) {
  console.log('Nombre: ' + n + ', Padre: ' + f);
}

// "Nombre: Mike Smith, Padre: Harry Smith"
// "Nombre: Tom Jones, Padre: Richard Jones"

Nombres de propiedades de objetos calculados y desestructuraci贸n

Los nombres de propiedad calculados, como en un Objeto literal, se pueden usar con la desestructuraci贸n.

let key = 'z';
let {[key]: foo} = {z: 'bar'};

console.log(foo); // "bar"

Rest en la desestructuraci贸n de objetos

La propuesta Propiedades rest/propagaci贸n para ECMAScript (etapa 4) agrega la sintaxis rest para desestructurar. Las propiedades de rest recopilan las claves de propiedades enumerables restantes que a煤n no han sido seleccionadas por el patr贸n de desestructuraci贸n.

let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }

Identificador de JavaScript no v谩lido como nombre de propiedad

La desestructuraci贸n se puede utilizar con nombres de propiedad que no son identificadores v谩lidos en JavaScript proporcionando un identificador alternativo que sea v谩lido.

const foo = { 'fizz-buzz': true };
const { 'fizz-buzz': fizzBuzz } = foo;

console.log(fizzBuzz); // "true"

Desestructuraci贸n combinada de arreglos y objetos

La desestructuraci贸n de arreglos y objetos se puede combinar. Supongamos que deseas manipular el tercer elemento del siguiente arreglo props, y luego deseas la propiedad name en el objeto, puedes hacer lo siguiente:

const props = [
  { id: 1, name: 'Fizz'},
  { id: 2, name: 'Buzz'},
  { id: 3, name: 'FizzBuzz'}
];

const [,, { name }] = props;

console.log(name); // "FizzBuzz"

Se busca la cadena de prototipos al desestructurar el objeto.

Al deconstruir un objeto, si no se accede a una propiedad en s铆 misma, continuar谩 buscando a lo largo de la cadena de prototipos.

let obj = {self: '123'};
obj.__proto__.prot = '456';
const {self, prot} = obj;
// self "123"
// prot "456" (Acceso a la cadena de prototipos)

Especificaciones

Compatibilidad del navegador

BCD tables only load in the browser

Ve tambi茅n