O que as chaves nas instruções `var {…} =…` fazem?

117

Não tenho certeza se esta é uma sintaxe JS específica do Mozilla, mas frequentemente encontro variáveis ​​sendo declaradas dessa forma, por exemplo, em documentos SDK complementares :

var { Hotkey } = require("sdk/hotkeys");

e em vários Javascript do Chrome (a letinstrução está sendo usada no lugar de var),

let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu }  = Components;

Achei muito confuso, mas não estou conseguindo encontrar nenhuma documentação sobre ambas as sintaxes, mesmo no MDN .

sonho do tempo
fonte
@Blender Como você pesquisaria essa estrutura em symbolhound.com?
trusktr
1
@trusktr: Um pouco tarde: symbolhound.com/…
Blender
A resposta curta está aqui: stackoverflow.com/a/45909752/203704
Cliff Hall
Estou bem com a desconstrução básica. No entanto, neste exemplo, também estamos atribuindo o valor a um nome de propriedade diferente e essa sintaxe é muito confusa. É o oposto da sintaxe de criação de objeto e isso adiciona ainda mais confusão.
Sol

Respostas:

72

Ambos são recursos do JavaScript 1.7. O primeiro são as variáveis ​​de nível de bloco :

letpermite que você declare variáveis, limitando seu escopo ao bloco, instrução ou expressão em que é usada. Isso é diferente da varpalavra - chave, que define uma variável globalmente ou localmente para uma função inteira, independentemente do escopo do bloco.

O segundo é chamado de desestruturação :

A atribuição de desestruturação torna possível extrair dados de matrizes ou objetos usando uma sintaxe que espelha a construção de literais de matriz e objeto.
...
Uma coisa particularmente útil que você pode fazer com a atribuição de desestruturação é ler uma estrutura inteira em uma única instrução, embora haja uma série de coisas interessantes que você pode fazer com ela, conforme mostrado na seção cheia de exemplos a seguir.

Para quem está familiarizado com Python, é semelhante a esta sintaxe:

>>> a, (b, c) = (1, (2, 3))
>>> a, b, c
(1, 2, 3)

O primeiro pedaço de código é uma abreviação de:

var {Hotkey: Hotkey} = require("sdk/hotkeys");
// Or
var Hotkey = require("sdk/hotkeys").Hotkey;

Você pode reescrever o segundo trecho de código como:

let Cc = Components.classes;
let Ci = Components.interfaces;
let Cr = Components.results;
let Cu = Components.utils;
Liquidificador
fonte
2
Pelo meu experimento, parece var { Hotkey }é equivalente a var { Hotkey: Hotkey }. Obrigado por localizar a documentação!
timdream
@timdream: Tive a sensação de que era algo assim, mas como isso difere var Hotkey = require(...).Hotkey? Ou está apenas salvando pressionamentos de tecla?
Blender
parece assim: - / (hehehe, esses programadores preguiçosos ...)
timdream
2
Além disso, torna tudo mais enigmático usar uma sintaxe tão incomum.
trusktr
O segundo é "Object Destructuring", refere-se a developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
IcyBrk
80

O que você está vendo é uma tarefa de desestruturação. É uma forma de correspondência de padrões como em Haskell.

Usando a atribuição de desestruturação, você pode extrair valores de objetos e matrizes e atribuí-los a variáveis ​​recém-declaradas usando a sintaxe literal de objeto e matriz. Isso torna o código muito mais sucinto.

Por exemplo:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var {a, b, c} = ascii;

O código acima é equivalente a:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var a = ascii.a;
var b = ascii.b;
var c = ascii.c;

Da mesma forma para matrizes:

var ascii = [97, 98, 99];

var [a, b, c] = ascii;

Isso é equivalente a:

var ascii = [97, 98, 99];

var a = ascii[0];
var b = ascii[1];
var c = ascii[2];

Você também pode extrair e renomear uma propriedade de objeto da seguinte maneira:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var {a: A, b: B, c: C} = ascii;

Isso é equivalente a:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var A = ascii.a;
var B = ascii.b;
var C = ascii.c;

Isso é tudo que há para fazer.

Aadit M Shah
fonte
12
1 para os exemplos de desestruturação de objetos, eles são realmente úteis. Os exemplos de MDN mostram apenas a desestruturação da matriz.
Blender
@Blender - Eles fornecem exemplos de desestruturação de objetos. Observe Looping entre valores em uma matriz de objetos .
Aadit M Shah
Eu quis dizer a var {a, b, c} = ascii;sintaxe.
Blender
Esse último exemplo é realmente estranho porque normalmente o que está à esquerda do cólon é o que está sendo atribuído.
Curtis
1

Esta é uma atribuição destruidora em Javascript e faz parte do padrão ES2015. Ele descompacta ou extrai valores de arrays ou propriedades de objetos em variáveis ​​distintas. Ex: Destruturação de Matriz

var foo = ["one", "two", "three"];
//without destructuring
var one = foo[0];
var two = foo[1];
var three = foo[2];

// com desestruturação var [um, dois, três] = foo

Ex: Destruturação de Objeto

var o = {p: 42, q: verdadeiro}; var {p, q} = o;

console.log (p); // 42 console.log (q); // verdade

// Atribuir novos nomes de variáveis ​​var {p: foo, q: bar} = o;

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

Deeksha Sharma
fonte
0

Há documentação para a letdeclaração no MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/let

leté semelhante a varporque limita o escopo da variável declarada. Ele permite que você declare uma variável dentro de um if(){}bloco (ou algum outro bloco) e tenha essa variável apenas "visível" dentro desse bloco (JavaScript, até agora, tem escopo de função e não escopo de bloco como a maioria das outras linguagens). Portanto, isso leté basicamente uma "correção" para algo que muitas pessoas têm problemas. Observe que esse é um recurso do JavaScript 1.7.

Não encontrei nada ligado {Foo}.

Jan Hančič
fonte
Desculpe, pensei que você estava perguntando sobre os dois ... Meu google-fu me falha quando se trata de {Foo}: /
Jan Hančič
Eu também: - / Google não indexa {e }.
timdream