Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does TypeScript pack a class in an IIFE?

Here is a TypeScript class:

class Greeter {
    public static what(): string {
        return "Greater";
    }

    public subject: string;

    constructor(subject: string) {
        this.subject = subject;
    }

    public greet(): string {
        return "Hello, " + this.subject;
    }
}

It is transpiled to IIFE when TS targets ES5:

var Greeter = /** @class */ (function () {
    function Greeter(subject) {
        this.subject = subject;
    }
    Greeter.what = function () {
        return "Greater";
    };
    Greeter.prototype.greet = function () {
        return "Hello, " + this.subject;
    };
    return Greeter;
}());

However, it generally works in the same way when it is presented as a constructor function. Which, of course, looks more JavaScriptish and handwritten :)

function Greeter(subject) {
    this.subject = subject;
}
Greeter.what = function () {
    return "Greater";
};
Greeter.prototype.greet = function () {
    return "Hello, " + this.subject;
};

Usage:

Both blocks of code work in the same way:

Greater.what();  // -> "Greater"
var greater = new Greater("World!");
greater.greet(); // -> "Hello, World!

What is the benefit or motives to pack it in IIFE?

I made a naive benchmark:

console.time("Greeter");
for(let i = 0; i < 100000000; i++) {
    new Greeter("world" + i);
}
console.timeEnd("Greeter");

It showed virtually the same instantiation speed. Of course, we cannot expect any difference, because the IIFE is resolved only once.

I was thinking that maybe it is because of closure, but the IIFE doesn't take arguments. It must not be a closure.

like image 481
Miroslav Popov Avatar asked May 11 '19 01:05

Miroslav Popov


People also ask

When should I use TypeScript class?

If you want to create and pass a type-checked class object, you should use TypeScript classes. If you need to work without creating an object, an interface is best for you.

Does TypeScript support multiple inheritance?

An inherited derived class acquires the properties and behaviors of the base class. TypeScript supports single inheritance and multilevel inheritance. We can not implement hybrid and multiple inheritances using TypeScript.

Which one of the following options correctly instantiates an object of a class in TypeScript?

A constructor is used to initialize an object. In TypeScript, the constructor method is always defined with the name "constructor." In the constructor, we can access the member of a class by using this keyword.

Which keyword is used to define class in TypeScript?

TypeScript defines a constructor using the constructor keyword. A constructor is a function and hence can be parameterized. The this keyword refers to the current instance of the class. Here, the parameter name and the name of the class's field are the same.


1 Answers

TypeScript will pass arguments to the IIFE in cases where there is inheritance between classes. For example, the closure below is used when Greeter extends a BaseGreeter class:

var Greeter = /** @class */ (function (_super) {
    // __extends is added by the TS transpiler to simulate inheritance
    __extends(Greeter, _super);
    function Greeter(subject) {
        var _this = _super.call(this) || this;
        _this.subject = subject;
        return _this;
    }
    Greeter.What = function () {
        return "Greater";
    };
    Greeter.prototype.greet = function () {
        return "Hello, " + this.subject;
    };
    return Greeter;
}(BaseGreeter));
like image 72
Peter Avatar answered Sep 23 '22 06:09

Peter