Why does TypeScript generate IIFE for the class?

Looking at this TypeScript code:

class Greeter { greet() {} } 

It generates an IFFE expression (an expression with an instant call function) around the constructor function and all declarations of the prototype functions, such as:

 var Greeter = (function () { function Greeter() { } Greeter.prototype.greet = function () { }; return Greeter; }()); 

What is the advantage? When I read about IIFE, I see a lot of use in defining modules. As far as I can see, TypeScript does not generate anything inside IIFE that would pollute the global namespace.

In my opinion, there is no advantage over this class declaration:

 var Greeter = function () {} Greeter.prototype.greet = function () { }; 

What is the reason for this?

+8
javascript class typescript
source share
2 answers

It is interesting. I think the typescript compiler compiles ClassDeclaration inferred from ClassExpression s by assigning the expression to a variable in scope, so they should not handle these cases independently. This simplifies the typescript compiler and makes the generated code somewhat modular (I would say more readable, but it's just a matter of taste).

 class Bar { }; foo(class Baz { }); var Baa = class Bab { }; 

Compiles to:

 var Bar = (function () { function Bar() { } return Bar; }()); ; foo((function () { function Baz() { } return Baz; }())); var Baa = (function () { function Bab() { } return Bab; }()); 

See, ClassDeclaration compiled as a ClassExpression assigned to a local variable.

+6
source share

To avoid global pollution of the namespace.

Its clousure pattern, where internal functions have access to their parents' properties. IIFE returns the LIST to internal functions.

The following are two scenarios where the IIFE pattern is quite useful and the reason why the TypeScript Compiler generates the IIFE pattern:

  • Inheritance: where it passes BaseClass as an argument to IIFE. If IIFEE were not there BaseClass , it would be a global variable, thus polluting the global namespace.

TypeScript

 class Greeter extends BaseController { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } } 

Js

 var Greeter = (function(_super) { __extends(Greeter, _super); function Greeter(message) { this.greeting = message; } Greeter.prototype.greet = function() { return "Hello, " + this.greeting; }; return Greeter; }(BaseController)); 
  1. Implementation of the module template: where the application has only one global variable of the type β€œapplication”, and all other functions are enclosed in objects such as app.cart , app.catalog , etc. Only the variable is displayed through the modules, and all other functions are added to the modules themselves, which is possible only for IIFE.

TypeScript

 module App.Controller { export class Greeter extends BaseController { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } } } 

Js

 var App; (function (App) { var Controller; (function (Controller) { var Greeter = (function (_super) { __extends(Greeter, _super); function Greeter(message) { this.greeting = message; } Greeter.prototype.greet = function () { return "Hello, " + this.greeting; }; return Greeter; }(BaseController)); Controller.Greeter = Greeter; })(Controller = App.Controller || (App.Controller = {})); })(App || (App = {})); 

Copy / Paste this js code into your browsers console and only the global version will be created only for the App variable. The stop function will be in the application.

Thank mkdudeja

+9
source share

All Articles