Artigo original: How to Use Array and Object Destructuring in JavaScript

A atribuição de desestruturação é um recurso interessante que veio com a ES6. Desestruturação é uma expressão do JavaScript que torna possível "desembalar" valores dos arrays ou propriedades de objetos em variáveis distintas. Ou seja, podemos extrair dados dos arrays e dos objetos e atribuí-los às variáveis.

Por que isso é necessário?

Imagine que queremos extrair dados de um array. Anteriormente, como isso seria feito?

let apresentacao = ["Olá", "eu" , "sou", "a", "Sarah"];
let saudacao = apresentacao[0];
let nome = apresentacao[4];

console.log(saudacao);//"Olá"
console.log(nome);//"Sarah"

Podemos ver que, quando queremos extrair dados de um array, temos de fazer o mesmo repetidamente.

A atribuição de desestruturação da ES6 torna mais fácil extrair esses dados. Como? Primeiro, discutiremos a atribuição de desestruturação com arrays. Em seguida, passaremos à desestruturação de objetos.

Vamos começar.

Desestruturação básica de arrays

Se quisermos extrair dados de arrays, isso é bastante simples usando a atribuição de desestruturação.

Vejamos nosso primeiro exemplo com arrays. Em vez de passar por um processo repetitivo, faremos isso:

let apresentacao = ["Olá", "eu" , "sou", "a", "Sarah"];
let [saudacao, pronome] = apresentacao;

console.log(saudacao);//"Olá"
console.log(pronome);//"eu"

Também podemos fazer o seguinte com o mesmo resultado.

let [saudacao, pronome] = ["Olá", "eu", "sou", "a", "Sarah"];

console.log(saudacao);//"Olá"
console.log(pronome);//"eu"

Declaração de variáveis antes da atribuição

As variáveis podem ser declaradas antes de serem atribuídas assim:


let saudacao, pronome;
[saudacao, pronome] = ["Olá", "eu" , "sou", "a", "Sarah"];

console.log(saudacao);//"Olá"
console.log(pronome);//"eu"

Observe que as variáveis são definidas da esquerda para a direita. Assim, a primeira variável recebe o primeiro item do array, a segunda variável recebe o segundo item do array e assim por diante.

Pulando itens em um array

E se quisermos obter o primeiro e o último item do nosso array, em vez do primeiro e do segundo item, e atribuir somente duas variáveis? Isso pode ser feito. Veja o exemplo abaixo:

let [saudacao,,,,nome] = ["Olá", "eu" , "sou", "a", "Sarah"];

console.log(saudacao);//"Olá"
console.log(nome);//"Sarah"

O que acaba de acontecer?

Olhe o array do lado esquerdo da atribuição de variável. Perceba que, em vez de termos apenas uma vírgula, temos quatro. O separador de vírgula é usado para saltar valores em um array. Assim, se quiser saltar um item no array, basta usar uma vírgula.

Vamos fazer outro exemplo. Vamos saltar o primeiro, o terceiro e o quarto item da lista. Como faremos isso?

let [,pronome,,,nome] = ["Olá", "eu" , "sou", "a", "Sarah"];

console.log(pronome);//"eu"
console.log(nome);//"Sarah"

É o separador de vírgulas que faz a mágica acontecer. Se quisermos pular todos os itens, é só fazermos isso:

let [,,,,,] = ["Olá", "eu" , "sou", "a", "Sarah"];

Atribuindo o resto de um array

E se quisermos atribuir parte de um array às variáveis e o resto dos itens a uma variável específica? Neste caso, podemos fazer isso:

let [saudacao,...apresentacao] = ["Olá", "eu" , "sou", "a", "Sarah"];

console.log(saudacao);//"Olá"
console.log(apresentacao);//["eu", "sou", "a", "Sarah"]

Usando esse padrão, é possível "desembalar" os itens e atribuir parte de um array a uma variável.

Atribuição de desestruturação com funções

Também podemos extrair dados de um array retornados de uma função. Digamos que temos uma função que retorna um array como o do exemplo abaixo:

function getArray() {
    return ["Olá", "eu", "sou" , "a", "Sarah"];
} 
let [saudacao,pronome] = getArray();

console.log(saudacao);//"Olá"
console.log(pronome);//"eu"

Obtemos os mesmos resultados.

Uso de valores padrão

Valores padrão podem ser atribuídos às variáveis em caso de um valor extraído de um array ser undefined:

let [saudacao = "Oi", nome = "Sarah"] = ["Olá"];

console.log(saudacao);//"Olá"
console.log(nome);//"Sarah"

Assim, nome retorna "Sarah", pois não está definido no array.

Alternância de valores usando a atribuição de desestruturação

Mais uma coisa: podemos usar a atribuição de desestruturação para alternar valores de variáveis:

let a = 3;
let b = 6;

[a,b] = [b,a];

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

Agora, passemos a desestruturação de objetos.

Desestruturação de objetos

Primeiro, vejamos o motivo de ser necessária a desestruturação de objetos.

Digamos que queremos extrair dados de um objeto e atribuí-lo a novas variáveis. Antes da ES6, como faríamos isso?

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

let nome = pessoa.nome;
let pais = pessoa.pais;
let profissao = pessoa.profissao;

console.log(nome);//"Sarah"
console.log(pais);//"Nigéria"
console.log(profissao);//Desenvolvedora"

Percebem o tédio que é extrair todos os dados? Temos que, repetidamente, fazer a mesma coisa. A desestruturação da ES6 é uma salvação, nesse sentido. Vamos ver como ela funciona.

Desestruturação básica de objetos

Vamos repetir o exemplo acima com a ES6. Em vez de atribuir valores um por um, podemos usar o objeto da esquerda para extrair os dados:

    
let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

let {nome, pais, profissao} = pessoa;

console.log(nome);//"Sarah"
console.log(pais);//"Nigéria"
console.log(profissao);//Desenvolvedora"

Você obtém os mesmos resultados. Isso também é válido para atribuir variáveis a um objeto que ainda não foi declarado:

let {nome, pais, profissao} = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

console.log(nome);//"Sarah"
console.log(pais);//"Nigéria"
console.log(profissao);//Desenvolvedora"

Variáveis declaradas antes da atribuição

As variáveis nos objetos podem ser declaradas antes de sua atribuição com a desestruturação. Vamos experimentar:

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};
let nome, pais, profissao;

{nome, pais, profissao} = pessoa;

console.log(nome);// Error : "Unexpected token ="

Opa! O que aconteceu? Ah, esquecemos de adicionar um () antes das chaves.

O ( ) ao redor da instrução de atribuição é necessário para a sintaxe ao usar a desestruturação de literais de objetos sem uma declaração. Isso ocorre, pois o {} do lado esquerdo é considerado um bloco, não um literal de objeto. Aqui temos, então, a sintaxe certa:

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};
let nome, pais, profissao;

({nome, pais, profissao} = pessoa);

console.log(nome);//"Sarah"
console.log(profissao);//"Desenvolvedora"

Também é importante observar que, ao usar essa sintaxe, o () deve ser precedido de um ponto-e-vírgula. Do contrário, ele pode ser usado para executar uma função da linha anterior.

Observe que as variáveis no objeto da esquerda devem ter o mesmo nome que a chave da propriedade no objeto pessoa. Se os nomes forem diferentes, teremos um undefined:

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

let {nome, amigos, profissao} = pessoa;

console.log(nome);//"Sarah"
console.log(amigos);//undefined

E se quisermos usar um novo nome de variável. Bem, isso também é possível.

Uso de um novo nome de variável

Se quisermos atribuir valores de um objeto a uma variável nova em vez de usar o nome da propriedade, podemos fazer isso:

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

let {nome: foo, profissao: bar} = pessoa;

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

Assim, os valores extraídos são passados para as novas variáveis foo e bar.

Uso de valores padrão

Valores padrão também podem ser usados em desestruturação de objetos, caso uma variável seja undefined em um objeto do qual ela deseja extrair dados:

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

let {nome = "meuNome", amiga = "Annie"} = pessoa;

console.log(nome);//"Sarah"
console.log(amiga);//"Annie"

Assim, se o valor não for undefined, a variável armazenará o valor extraído do objeto, como no caso de nome. Do contrário, é usado o valor padrão, como em amiga.

Também podemos definir valores padrão ao atribuir valores a uma nova variável:

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

let {nome:foo = "meuNome", amiga: bar = "Annie"} = pessoa;

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

Aqui,  nome foi extraído de pessoa e atribuído a uma variável diferente. amiga, por outro lado, era undefined em pessoa, por isso a nova variável bar  recebeu o valor padrão.

Nome de propriedade computado

O nome de propriedade computado é outro recurso de literais de objetos que também funciona para a desestruturação. Você pode especificar o nome de uma propriedade por meio de uma expressão se você o colocar entre colchetes:

let prop = "nome";

let {[prop] : foo} = {nome: "Sarah", pais: "Nigéria", profissao: "Desenvolvedora"};

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

Combinação de arrays com objetos

Arrays também podem ser usados com objetos na desestruturação de objetos:

let pessoa = {nome: "Sarah", pais: "Nigéria", amigas: ["Annie", "Becky"]};

let {nome:foo, amigas: bar} = pessoa;

console.log(foo);//"Sarah"
console.log(bar);//["Annie", "Becky"]

Aninhamento em desestruturação de objetos

Objetos também podem ser aninhados na desestruturação:

let pessoa = {
    nome: "Sarah",
    local: {
        pais: "Nigéria", 
        cidade: "Lagos" }, 
    amigas : ["Annie", "Becky"]
};

let {nome:foo,
     local: {
         pais : bar,
         cidade : x}
    } = pessoa;

console.log(foo);//"Sarah"
console.log(bar);//"Nigéria"

Rest em desestruturação de objetos

A sintaxe de rest também pode ser usada para buscar as chaves de propriedade que já não foram coletadas pelo padrão de desestruturação. Essas chaves e valores são copiados para um novo objeto:

let pessoa = {nome: "Sarah", pais: "Nigéria", profissao: "Developer", amigas: ["Annie", "Becky"]};

let {nome, amigas, ...outros} = pessoa;

console.log(nome);//"Sarah"
console.log(amigas);//["Annie", "Becky"]
console.log(outros);// {pais: "Nigéria", profissao: "Desenvolvedora"}

Aqui, as propriedades restantes, cujas chaves não eram parte dos nomes de variáveis listados anteriormente, foram atribuídas à variável outros. A sintaxe de rest aqui é ...outros. outros pode ser renomeado com o nome que você desejar.

Para encerrar, vejamos como a desestruturação de objetos pode ser usada nas funções.

Desestruturação de objetos e funções

A desestruturação de objetos pode ser usada para atribuir parâmetros a funções:

function pessoa({nome: x, profissao: y} = {}) {
    console.log(x);
}

pessoa({nome: "Michelle"});//"Michelle"
pessoa();//undefined
pessoa(amiga);//Error : amiga is not defined

Observe o {} no lado direito do objeto dos parâmetros. Isso torna possível chamarmos a função sem passar argumentos. É por isso que temos um undefined. Se o removermos, temos uma mensagem de erro.

Também podemos atribuir valores padrão aos parâmetros:

function pessoa({nome: x = "Sarah", profissao: y = "Desenvolvedora"} = {}) {
    console.log(x);
}

person({nome});//"Sarah"

É possível fazer muitas e muitas coisas com a desestruturação de arrays e objetos, como vimos nos exemplos acima.

Obrigado pela leitura. :)