¿Por qué una enumeración transstack en una function?

Considerar:

enum Colors { Red, Green, Blue } 

Transstack en esto:

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

La mayoría de las preguntas sobre este resultado se responden en Enumeraciones en TypeScript: ¿qué está haciendo el código JavaScript? .

Cito las respuestas:

Esta es una 'function de ejecución inmediata'

Y más abajo en el tema:

Creo que probablemente podrían ir:

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

y omita el cierre, pero tal vez todavía me falta algo.

Entonces, la pregunta sigue siendo: ¿por qué envolver esto en una function de ejecución inmediata?

Creo que TypeScript usa IIFE (también conocida como expresión de function invocada inmediatamente) porque el nombre de la variable puede ser minimizado. Si tiene un nombre enum muy largo, p. Ej. MySuperAmazingStatesNeededForWhateverIWantEnum , puede ser minificado dentro de un IIFE a solo una letra

 // 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[et=0]="Red",e[eu=1]="Green",e[em=2]="Blue"}(MySuperAmazingStatesNeededForWhateverIWantEnum||(MySuperAmazingStatesNeededForWhateverIWantEnum={})); 

Sin IIFE, la minificación no sería tan efectiva

 // 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"; 

La diferencia de tamaño es enorme.

Eso es porque en TypeScript los Enums son abiertos.

Esto significa que puedes hacer algo como a continuación:

 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 } 

Eso significa que puede agregar nuevos miembros a una enum ya definida. Considere esto como una class parcial en C # o interface s en typescript.

El IIFE se usa para que cualquier definición existente (object de lectura) de la enum del mismo nombre pueda ser recogido.

Además, TypeScript muestra correctamente los informes del siguiente error si omitimos = 3 partes de la segunda definición de enum Colors .

En una enumeración con múltiples declaraciones, solo una statement puede omitir un inicializador para su primer elemento enum.

(miembro enum) Colors.Black = 0

Lea más aquí: https://basarat.gitbooks.io/typescript/docs/enums.html

EDITAR: También tenga en count que hay algunos beneficios de usar IIFE.

  1. Optimización del scope local: siempre es beneficioso declarar su variable lo más cerca posible de su primer uso de esa variable. JavaScript puede atravesar desde el ámbito local hasta el scope global para search una variable. Por lo tanto, usar una variable local puede proporcionar un beneficio de performance.
  2. Minificación: esto ya se menciona en la respuesta de @Piotr Kocia . Significa que también puede usar nombres de variables más cortos para el IIFE.

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

    Puede que esto no parezca una proposition tan lucrativa en este momento, pero considere cuándo su nombre de variable es más largo.

Más sobre el tema "Por qué IIFE": http://gregfranko.com/blog/i-love-my-iife/

Espero que esto ayude.