Looking at this TypeScript code:
class Greeter {
greet() {}
}
It generates an IIFE (Immediately-Invoked Function Expression) around the constructor function and all prototype function declarations like:
var Greeter = (function () {
function Greeter() {
}
Greeter.prototype.greet = function () { };
return Greeter;
}());
What is the advantage here? When ever I read about IIFE I see a lot usage in defining modules. As far as I can see Typescript does not generate anything inside the 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 it?
An Immediately-invoked Function Expression (IIFE for friends) is a way to execute functions immediately, as soon as they are created. IIFEs are very useful because they don't pollute the global object, and they are a simple way to isolate variables declarations.
An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined. The name IIFE is promoted by Ben Alman in his blog. (function () { // … })(); (() => { // … })(); (async () => { // …
Immediately-Invoked Function Expressions (IIFE), pronounced "iffy", are a common JavaScript pattern that executes a function instantly after it's defined. Developers primarily use this pattern to ensure variables are only accessible within the scope of the defined function.
(function () { })(); This is called IIFE (Immediately Invoked Function Expression).
To avoid global namespace pollution.
Its a clousure pattern where inner functions have access to their parents properties. By IIFE, REFERENCE to inner functions returned.
Below are two scenarios, where IIFE pattern is quite helpful and the reason, why TypeScript Compiler generates IIFE pattern:
BaseClass
as an argument to IIFE. If IIFEE would not have been there BaseClass
would be 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));
app.cart
, app.catalog
etc. There only variable is exposed through modules and all other features are added to the modules itself, which is possible by IIFE only.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 to browsers console and only App variable will be globally created. Rest functionality will be under App.
Thanks, mkdudeja
That is interesting. I think the typescript compiler compiles ClassDeclaration
deduced from ClassExpression
s, by assigning the expression to a variable in the scope, so they don't have to handle those cases independently. This simplifies the TypeScript compiler, and makes the generated code somewhat modular (I would say more readable, but that's just a matter of taste).
class Bar { };
foo(class Baz { });
var Baa = class Bab { };
Compiles into:
var Bar = (function () {
function Bar() {
}
return Bar;
}());
;
foo((function () {
function Baz() {
}
return Baz;
}()));
var Baa = (function () {
function Bab() {
}
return Bab;
}());
See, the ClassDeclaration
is compiled as a ClassExpression
assigned to a local variable.
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