2013-11-29 14 views
9

Die folgende Typoskript:Enums in TypeScript: Was macht der JavaScript-Code?

enum PrimaryColors { Red, Green, Blue }; 

erzeugt folgende JavaScript:

var PrimaryColors; 
(function (PrimaryColors) { 
    PrimaryColors[PrimaryColors["Red"] = 0] = "Red"; 
    PrimaryColors[PrimaryColors["Green"] = 1] = "Green"; 
    PrimaryColors[PrimaryColors["Blue"] = 2] = "Blue"; 
})(PrimaryColors || (PrimaryColors = {})); 
; 

Ich bin peinlich zugeben, dass ich nicht verstehe, was der JavaScript tut.
Die Funktion in Klammern weist String-Werte unter Verwendung einer anderen Zuweisung als Index/Schlüssel zu. So etwas habe ich noch nie gesehen.
Und was ist der Zweck der (PrimaryColors || (PrimaryColors = {}) nach der Funktion?
Wenn die Antwort ist, JavaScript richtig zu lernen, werde ich bereitwillig akzeptieren, vorausgesetzt es kommt mit einer vorgeschlagenen Quelle, die deutlich erklärt ., was ich hier sehe

Antwort

9

ich glaube:

PrimaryColors[PrimaryColors["Red"] = 0] = "Red"; 

gleichwertig ist.

PrimaryColors[0] = "Red"; 
PrimaryColors["Red"] = 0; 

dieses reference Siehe

Der Ausdruck x = 7 ist ein Beispiel für den ersten Typ. Dieser Ausdruck verwendet den Operator =, um der Variablen x den Wert sieben zuzuweisen. Der Ausdruck selbst ergibt sieben.

Zum Beispiel:

console.log((x = 7)); 

Ausgänge:

7 

Ähnlich:

var x = {}; 
console.log((x["hi"] = 7)); 

gibt ebenfalls 7.


Für die zweite Sache ist PrimaryColors zunächst undefiniert.

var x; 
console.log(x); // undefined 

In einem Booleschen Kontext wertet undefined-false:

console.log(!undefined); // true 
console.log(!!undefined); // false 

Plausibiltätsprüfung:

console.log((!undefined) === true); // true 
console.log((!!undefined) === false); // true 
console.log(undefined === false); // false 

Dies ist eine gemeinsame Nutzung von Kurzschlüssen. Da PrimaryColors anfänglich nicht definiert ist (false), wird {} an die Funktion übergeben.

PrimaryColors || (PrimaryColors = {}) 
+0

"..., es wird {} an die Funktion übergeben." sollte sein: "..., es wird als leeres Objekt initialisiert, welches dann an die Funktion übergeben wird. –

7

Vielleicht wird dies helfen.

(function() {})(); 

Dies ist eine 'sofort ausführende Funktion'. Er definiert eine Funktion als Ausdruck und ruft sie dann auf.

var x = y || y = {}; 

Wenn ein gemeinsames Muster für die Initialisierung von etwas auf einen Standardwert. Wenn y keinen Wert hat, ist der 1. Teil der Oder-Anweisung falsch und führt den 2. Teil aus, der y einen Wert zuweist. Der Wert dieses zweiten Ausdrucks ist der neue Wert von y. Also wird x der Wert von y - was der neue Wert ist, wenn er nicht bereits definiert wurde.

x[y] = z; 

Objekte in JS sind assoziative Arrays. Mit anderen Worten, String-Objekt-Paare, wie IDictionary (String, Objekt). Dieser Ausdruck setzt den Schlüssel mit dem Wert y auf den Wert von z im Wörterbuch x;

x[x["a"] = 0] = "a"; 

So, die gleiche Sache hier, aber mit einem verschachtelten Ausdruck, das ist:

x["a"] = 0; 

dass So setzt nur den Wert des Schlüssel "a". Nichts Außergewöhnliches. Aber das ist auch ein Ausdruck, dessen Wert 0. So ersetzen, dass in den ursprünglichen Ausdruck:

x[0] = "a"; 

Keys müssen Strings sein, also ist es eigentlich das gleiche wie:

x["0"] = "a"; 

, die gerade legt einen weiteren Schlüssel im Wörterbuch fest. Das Ergebnis ist, dass diese Aussagen zutreffen:

x["0"] === "a"; 
x["a"] === 0; 
0

ich diese Frage gefunden, weil ich mich gefragt, warum ein IIFE verwenden überhaupt, wenn man einfach die var mit {} init rechts ab. Die vorherigen Antworten decken es nicht ab, aber ich habe meine Antwort in der TypeScript Deep Dive gefunden.

Die Sache ist, enums können in mehrere Dateien aufgeteilt werden. Sie müssen nur explizit das erste Mitglied der zweiten, dritten, usw. Aufzählungen initialisieren, so folgt aus:

enum Colors { 
    Red, 
    Green, 
    Blue 
} 

enum Colors { 
    Cyan = 3, 
    Magenta, 
    Lime 
} 

transpiles dazu:

var Colors; 
(function (Colors) { 
    Colors[Colors["Red"] = 0] = "Red"; 
    Colors[Colors["Green"] = 1] = "Green"; 
    Colors[Colors["Blue"] = 2] = "Blue"; 
})(Colors || (Colors = {})); 
var Colors; 
(function (Colors) { 
    Colors[Colors["Cyan"] = 3] = "Cyan"; 
    Colors[Colors["Magenta"] = 4] = "Magenta"; 
    Colors[Colors["Lime"] = 5] = "Lime"; 
})(Colors || (Colors = {})); 

Wie Sie wahrscheinlich wissen, eine Variable innerhalb derselben erneut deklariert werden Umfang ist harmlos, aber Reinitialisierung ist nicht.

Ich denke, sie könnten wahrscheinlich nur gehen:

var Colors; 
Colors || (Colors = {}); 
Colors[Colors["Cyan"] = 3] = "Cyan"; 
// ... 

und die Schließung überspringen, aber vielleicht fehlt mir noch etwas.