Was bewirken geschweifte Klammern in den Anweisungen `var {…} =…`?

117

Ich bin mir nicht sicher, ob dies eine Mozilla-spezifische JS-Syntax ist, aber ich habe häufig festgestellt, dass Variablen auf diese Weise deklariert werden, z. B. in SDK-Zusatzdokumenten :

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

und in verschiedenen Chrom-Javascript ( letAussage wird anstelle von verwendet var),

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

Ich fand es sehr verwirrend, aber ich kann keine Dokumentation über beide Syntax finden, selbst auf MDN .

Timdream
quelle
@Blender Wie würden Sie auf symbolhound.com nach dieser Struktur suchen?
Trusktr
1
@trusktr: Ein bisschen spät: symbolhound.com/…
Blender
Die kurze Antwort ist hier: stackoverflow.com/a/45909752/203704
Cliff Hall
Mir geht es gut mit der grundlegenden Dekonstruktion. In diesem Beispiel weisen wir den Wert jedoch auch einem anderen Eigenschaftsnamen zu, und diese Syntax ist sehr, sehr verwirrend. Es ist der Syntax der Objekterstellung entgegengesetzt und sorgt für noch mehr Verwirrung.
Sol

Antworten:

72

Sie sind beide JavaScript 1.7-Funktionen. Die erste sind Variablen auf Blockebene :

letMit dieser Option können Sie Variablen deklarieren und ihren Gültigkeitsbereich auf den Block, die Anweisung oder den Ausdruck beschränken, für den sie verwendet werden. Dies unterscheidet sich vom varSchlüsselwort, mit dem eine Variable global oder lokal für eine gesamte Funktion unabhängig vom Blockbereich definiert wird.

Die zweite heißt Destrukturierung :

Die Destrukturierungszuweisung ermöglicht das Extrahieren von Daten aus Arrays oder Objekten mithilfe einer Syntax, die die Konstruktion von Array- und Objektliteralen widerspiegelt.
...
Eine besonders nützliche Sache, die Sie mit der Destrukturierungszuweisung tun können, ist das Lesen einer gesamten Struktur in einer einzigen Anweisung, obwohl Sie eine Reihe interessanter Dinge damit tun können, wie im folgenden Abschnitt mit Beispielen gezeigt.

Für diejenigen, die mit Python vertraut sind, ähnelt es dieser Syntax:

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

Der erste Codeblock ist eine Abkürzung für:

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

Sie können den zweiten Codeblock wie folgt umschreiben:

let Cc = Components.classes;
let Ci = Components.interfaces;
let Cr = Components.results;
let Cu = Components.utils;
Mixer
quelle
2
Aus meinem Experiment geht hervor, var { Hotkey }ist gleichbedeutend mit var { Hotkey: Hotkey }. Vielen Dank, dass Sie die Dokumentation gefunden haben!
Timdream
@ Timdream: Ich hatte das Gefühl, dass es so etwas war, aber wie unterscheidet sich das von var Hotkey = require(...).Hotkey? Oder werden nur Tastenanschläge gespeichert?
Blender
sieht so aus: - / (hehehe, diese faulen Programmierer ...)
timdream
2
Außerdem macht es alles kryptischer, eine so ungewöhnliche Syntax zu verwenden.
Trusktr
Die zweite ist "Object Destructuring", siehe Entwickler.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
IcyBrk
79

Was Sie sehen, ist eine Destrukturierungsaufgabe. Es ist eine Form des Mustervergleichs wie in Haskell.

Mithilfe der Destrukturierungszuweisung können Sie Werte aus Objekten und Arrays extrahieren und sie neu deklarierten Variablen mithilfe der Objekt- und Array-Literal-Syntax zuweisen. Dies macht den Code viel prägnanter.

Beispielsweise:

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

var {a, b, c} = ascii;

Der obige Code entspricht:

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

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

Ähnliches gilt für Arrays:

var ascii = [97, 98, 99];

var [a, b, c] = ascii;

Dies entspricht:

var ascii = [97, 98, 99];

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

Sie können eine Objekteigenschaft auch wie folgt extrahieren und umbenennen:

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

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

Dies entspricht:

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

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

Das ist alles dazu.

Aadit M Shah
quelle
11
+1 für die Beispiele zur Objektzerstörung sind sie wirklich hilfreich. Die MDN-Beispiele zeigen nur die Array-Destrukturierung.
Blender
@Blender - Sie bieten Beispiele für die Objektzerstörung. Sehen Sie sich das Schleifen über Werte in einem Array von Objekten an .
Aadit M Shah
Ich meinte die var {a, b, c} = ascii;Syntax.
Blender
Das letzte Beispiel ist wirklich seltsam, weil normalerweise links vom Doppelpunkt das zugewiesen wird.
Curtis
1

Dies ist eine zerstörerische Aufgabe in Javascript und Teil des ES2015-Standards. Es entpackt oder extrahiert Werte aus Arrays oder Eigenschaften von Objekten in verschiedene Variablen. ZB: Array-Destrukturierung

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

// mit Destrukturierung var [eins, zwei, drei] = foo

ZB: Objektzerstörung

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

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

// Neue Variablennamen zuweisen var {p: foo, q: bar} = o;

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

Deeksha Sharma
quelle
0

Es gibt eine Dokumentation für die letAnweisung auf MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/let

letist insofern ähnlich var, als es den Umfang der deklarierten Variablen einschränkt. Sie können damit eine Variable innerhalb eines if(){}Blocks (oder eines anderen Blocks) deklarieren und diese Variable nur in diesem Block "sichtbar" machen (JavaScript hat bisher einen Funktionsumfang und keinen Blockumfang wie die meisten anderen Sprachen). Das letist also im Grunde eine "Lösung" für etwas, mit dem viele Leute Probleme haben. Beachten Sie, dass tihs eine JavaScript 1.7-Funktion ist.

Ich habe nichts gefunden {Foo}.

Jan Hančič
quelle
Entschuldigung, ich dachte, Sie fragen nach beidem ... Mein Google-Fu versagt mir, wenn es um {Foo}
Folgendes
Ich auch: - / Google indiziert nicht {und }.
Timdream