What is the reason behind TypeScript enclosing a class within an IIFE (Immediately Invoked Function

Behold the mighty TypeScript class:

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

    public target: string;

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

    public salute(): string {
        return "Greetings, " + this.target;
    }
}

When TS aims for ES5, it morphs into an IIFE:

var Saluter = /** @class */ (function () {
    function Saluter(target) {
        this.target = target;
    }
    Saluter.what = function () {
        return "Greater";
    };
    Saluter.prototype.salute = function () {
        return "Greetings, " + this.target;
    };
    return Saluter;
}());

Nevertheless, it behaves similarly when presented as a traditional constructor function. It looks more like JavaScript in its natural state :)

function Saluter(target) {
    this.target = target;
}
Saluter.what = function () {
    return "Greater";
};
Saluter.prototype.salute = function () {
    return "Greetings, " + this.target;
};

Application:

Both versions function identically:

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

What are the advantages or reasons for wrapping it in an IIFE?

I conducted a basic benchmark test:

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

The results exhibited virtually identical instantiation speeds. This is expected since the IIFE is only resolved once.

I pondered if it might be due to closure, but the IIFE doesn't accept arguments. So, it cannot be a closure.

Answer №1

When classes are inherited, TypeScript will automatically pass arguments to the Immediately Invoked Function Expression (IIFE). An example of this can be seen in the code snippet below where Greeter extends a BaseGreeter class:

var Greeter = /** @class */ (function (_super) {
    // The __extends method is included by the TS transpiler to mimic 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));

Answer №2

To ensure proper functionality of native classes in specific scenarios like this one, precautions must be taken to prevent issues that may arise when attempting to utilize a class such as Greeter before it has been declared:

// The following code snippet is written in JavaScript, not TypeScript

console.log(Greeter.What());

class Greeter {
}

Greeter.What = function What() {
    return "Greater";
}

If using native class implementation, the expected output should be

ReferenceError: Greeter is not defined
.

Once transpiled and enclosed within an Immediately Invoked Function Expression (IIFE), the outcome is similar:

TypeError: Cannot read property 'What' of undefined
.

In cases where an IIFE is omitted, an unwrapped function gets hoisted and the name Greeter exists in the scope prior to its definition, resulting in a different error message:

TypeError: Greeter.What is not a function

It's important to note that IIFE isn't utilized for concealing private instance or class properties due to its unnecessary nature. Upon transpilation, instance properties are assigned as constructor properties using this, while static properties are set as properties of the Greeter object - no additional variables are introduced.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combining edit and view functionalities in jqGrid form

I've been exploring the jqGrid wiki but I'm having trouble finding answers to a couple of things. It seems like it might be too customized. 1) Can jqGrid be configured to display all fields of a row when editing via form edit, but only make a fe ...

Using jQuery to open a new window and automatically inputting a value into the textbox

I've been struggling with a basic concept for hours now and all my Google searches have turned up empty. I'm working with an HTML file that contains a div which, when clicked, should open a new window. In this new window, the input box should dis ...

Tips for integrating TypeScript files into Next.js HTML files

Encountering an issue while trying to load a typescript file from HTML, resulting in this error Here is the code snippet for the page: export default function Home() { return ( <> <Script src="/static/main.tsx"></Scri ...

Issue arises when compiling React Redux due to a union type that includes undefined

I am currently in the process of learning how to integrate Redux with React using Typescript. I encountered a compilation error that relates to the type of my store's state, specifically as {posts: PostType[]}. The error message states: Type '{ p ...

How to reference an image located in one folder from a page in a different folder using React

Imagine there is Folder A containing an image called 'image.jpg' and Folder B with an HTML page that needs to access the image in Folder A in order to display it. The following code successfully accomplishes this task: <img src={require(&apo ...

What would be the best way to structure this workflow as a JavaScript data format?

I have a complex workflow that I need to represent as a JavaScript data structure. This workflow involves a series of questions and answers where the response to one question determines the next one asked. Here is a basic example of what this workflow migh ...

Update the html() function to include any content that has been typed into a

I have a webpage structured like this: <div id="report_content"> Some information <textarea name="personal"></textarea> <b>Other information</b> <textarea name="work"></textarea> </div> Whe ...

The icon is being displayed as text instead of the actual Fontawesome icon

Using jquery version 3.3.1 I am dynamically creating an anchor tag: let link = $("<a>"); link.attr("href", "#"); link.text("My anchor" + ' <i class="fas fa-people-carry"></i>'); However, when I try to display ...

Submitting form by clicking a link on the page

To submit a POST request with "amount=1" without displaying it in the URL, I need the site to send this request when any link on the site is clicked. This JavaScript code achieves that with a GET request: window.onload = function () { document.body.oncli ...

Show the value in the input text field if the variable is present, or else show the placeholder text

Is there a ternary operator in Angular 1.2.19 for templates that allows displaying a variable as an input value if it exists, otherwise display the placeholder? Something like this: <input type="text "{{ if phoneNumber ? "value='{{phoneNumber}}&a ...

Ordering ng-repeat in AngularJS using a separate arrayDiscover how to easily order your

Imagine I have an array containing keys in a specific order orderedItems=["apple","banana","orange]; and there is a JSON object that I want to display using ng-repeat but following the sequence specified in the array: {"fruits": { "apple":{ ...

Manipulate classes by adding or removing them on click events in Angular

I am struggling to implement the angular ngClass for adding a class with a click event. Despite calling a function that should change the value of the "isExpandedConectivity" variable when clicking on the "li" element, it doesn't seem to work as expec ...

ReactJS: Error in syntax detected in src/App.js at line 16, column 6. This token is unexpected

Just starting out with reactjs and encountered a simple example in a tutorial. Ran into a syntax error when trying to return html tags. Below is the error that popped up: ./src/App.js Syntax error: C:/Users/react-tutotial/src/App.js: Unexpected token ...

Unable to pass on error from Express server to React client app

Background Overview In my project, I've implemented a React component named 'Register.jsx' where users can input their desired username and password. Upon clicking the submit button, this information is transmitted to an Express backend whi ...

What is preventing Javascript from executing a function when there is an error in another function?

Can you explain why a JavaScript function fails to run if there is an error in another function? Recently, I encountered an issue on my HTML page where the alert from the popup1() function would not load. It turns out the problem stemmed from an error in ...

Access to this feature is restricted when using a decorator in TypeScript with NodeJS

I have designed a decorator to handle async errors, but I am encountering difficulties in accessing it within class methods. My goal is to develop a reusable CRUD class that other classes can inherit from, with a method for CRUD operations. Decorator Code ...

What is the best way to implement a slide-down animation on a stateless component in React JS using either ReactCSStransitionGroup or ReactTransition

I am looking to create an animation for a stateless component that starts off with display:none, and then becomes visible when the parent component's state changes. I want it to slide down like a dropdown menu effect. I am new to animations and have b ...

Resetting the internal state in Material UI React Autocomplete: A step-by-step guide

My objective is to refresh the internal state of Autocomplete, a component in Material-UI. My custom component gets rendered N number of times in each cycle. {branches.map((branch, index) => { return ( <BranchSetting key={ind ...

Deciphering the JavaScript code excerpt

This information was sourced from (function ($, undefined) { // more code ... $.getJSON("https://api.github.com/orgs/twitter/members?callback=?", function (result) { var members = result.data; $(function () { $("#num- ...

A guide to programmatically downloading a file with JavaScript on Internet Explorer

I'm currently facing a challenge with my web page. There is a button that, when clicked, should generate a CSV file (by converting from JSON) for the user to download. I've implemented the logic based on this jsfiddle, and it works perfectly in C ...