Enums in TypeScript: what is the JavaScript code doing?

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-01 03:15:27

I believe:

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

is equivalent to:

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

See this reference.

The expression x = 7 is an example of the first type. This expression uses the = operator to assign the value seven to the variable x. The expression itself evaluates to seven.

For example:

console.log((x = 7));

outputs:

7

Similarly:

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

Also outputs 7.


As for the second thing, PrimaryColors is initially undefined.

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

In a boolean context, undefined evaluates to false:

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

Sanity check:

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

This is a common usage of short circuiting. Because PrimaryColors is initially undefined (false), it will pass {} to the function.

PrimaryColors || (PrimaryColors = {})

Maybe this will help.

(function() {})();

This is an 'immediately executing function'. It defines a function as an expression, and then invokes it.

var x = y || y = {};

If a common pattern for initializing something to a default value. If y does not have a value, the 1st part of the or-statement is false, so it executes the 2nd part, which assigns a value to y. The value of that 2nd expression is the new value of y. So x becomes that value of y -- which is the new value if it wasn't already defined.

x[y] = z;

Objects in JS are associative arrays. In other words, string-object pairs, like IDictionary(string,object). This expression is setting the key with value y to the value of z, in the dictionary x;

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

So, same thing here, but with a nested expression, which is:

x["a"] = 0;

So that just sets the value of key "a". Nothing fancy. But this is also an expression, whose value is 0. So substitute that in the original expression:

x[0] = "a";

Keys need to be strings, so it's actually the same thing as:

x["0"] = "a";

Which just sets yet another key in the dictionary. Result is that these statements are true:

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

I found this question because I was wondering why use an IIFE at all when you can just init the var with {} right off. The previous answers don’t cover it, but I’ve found my answer in the TypeScript Deep Dive.

The thing is, enums can be split into multiple files. You just have to explicitly initialize the first member of second, third, etc. enums, so this:

enum Colors {
    Red,
    Green,
    Blue
}

enum Colors {
    Cyan = 3,
    Magenta,
    Lime
}

transpiles to this:

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 = {}));

As you probably know, redeclaring a variable within the same scope is harmless, but reinitialization is not.

I think they could probably just go:

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

and skip the closure, but maybe I’m still missing something.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!