Consider:
enum Colors {
Red,
Green,
Blue
}
It transpiles into this:
var Colors;
(function (Colors) {
Colors[Colors["Red"] = 0] = "Red";
Colors[Colors["Green"] = 1] = "Green";
Colors[Colors["Blue"] = 2] = "Blue";
})(Colors || (Colors = {}));
Most questions about this result are answered in Enums in TypeScript: what is the JavaScript code doing?.
I quote the answers:
This is an 'immediately executing function'
And further down the topic:
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.
So the question remains: why wrapping this in an immediately executing function?
I believe TypeScript uses IIFE (aka immediately-invoked function expression) because the variable name can be minified. If you have really long enum name, e.g. MySuperAmazingStatesNeededForWhateverIWantEnum
, it can be minified inside an IIFE to just one letter
// amazing_enum.js
var MySuperAmazingStatesNeededForWhateverIWantEnum;
(function MySuperAmazingStatesNeededForWhateverIWantEnum() {
MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum["Red"] = 0] = "Red";
MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum["Green"] = 1] = "Green";
MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum["Blue"] = 2] = "Blue";
})(MySuperAmazingStatesNeededForWhateverIWantEnum || (MySuperAmazingStatesNeededForWhateverIWantEnum = {}));
// amazing_enum.min.js
var MySuperAmazingStatesNeededForWhateverIWantEnum;!function e(){e[e.t=0]="Red",e[e.u=1]="Green",e[e.m=2]="Blue"}(MySuperAmazingStatesNeededForWhateverIWantEnum||(MySuperAmazingStatesNeededForWhateverIWantEnum={}));
Without IIFE minification wouldn't be as effective
// amazing_enum.js
var MySuperAmazingStatesNeededForWhateverIWantEnum;
MySuperAmazingStatesNeededForWhateverIWantEnum || (MySuperAmazingStatesNeededForWhateverIWantEnum = {}),
MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum.Red = 0] = "Red";
MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum.Green = 1] = "Green";
MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum.Blue = 2] = "Blue";
// amazing_enum.min.js
var MySuperAmazingStatesNeededForWhateverIWantEnum;MySuperAmazingStatesNeededForWhateverIWantEnum||(MySuperAmazingStatesNeededForWhateverIWantEnum={}),MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum.t=0]="Red",MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum.u=1]="Green",MySuperAmazingStatesNeededForWhateverIWantEnum[MySuperAmazingStatesNeededForWhateverIWantEnum.m=2]="Blue";
The difference in size is huge.
That's because in TypeScript Enums are open ended.
This means that you can do something like below:
enum Colors {
Red,
Green,
Blue
}
console.log(Colors); // { '0': 'Red', '1': 'Green', '2': 'Blue', Red: 0, Green: 1, Blue: 2 }
enum Colors {
Black = 3,
White
}
console.log(Colors); // { '0': 'Red', '1': 'Green', '2': 'Blue', '3': 'Black', '4': 'White', Red: 0, Green: 1, Blue: 2, Black: 3, White: 4 }
That means that you can add new members to an already defined enum
. Consider this as partial class in C# or interface
s in typescript.
The IIFE is used so that any existing definition (read object) of enum
of the same name can be picked up.
Also TypeScript correctly shows reports the below error if we omit = 3
part from the second enum Colors
definition.
In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
(enum member) Colors.Black = 0
Read more here: https://basarat.gitbooks.io/typescript/docs/enums.html
EDIT: Also note that there are some benefit of using IIFE.
Minification: this is already mentioned in the answer by @Piotr Kocia. It means that you can also use shorter variable names for the IIFE.
var Colors;
(function (C) {
C[C["Red"] = 0] = "Red";
C[C["Green"] = 1] = "Green";
C[C["Blue"] = 2] = "Blue";
})(Colors || (Colors = {}));
This might not look a so lucrative proposition at this point but consider when you variable name is longer.
More on the topic "Why IIFE": http://gregfranko.com/blog/i-love-my-iife/
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With