Artigo original escrito por: Sarah Chima Atuonwu
Artigo original: How to Use Array and Object Destructuring in JavaScript
Traduzido e adaptado por: Daniel Rosa
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. :)