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 .


@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;

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.


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


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}.


Entschuldigung, ich dachte, Sie fragen nach beidem ... Mein Google-Fu versagt mir, wenn es um {Foo}
Folgendes

Ich auch: - / Google indiziert nicht {und }.
Timdream
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.