0

I was following a tutorial where they used a translator to translate a class in Typescript into javascript. The translated javascript is a bit confusing and I was wondering if someone can explain to me what the code is doing.

Original Typescript:

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

and the translated Javascript:

var Greeter = (function(){
    function Greeter(message){
        this.greeting = message;
    }
    Greeter.prototype.greet = function(){
        return "Hello, " + this.greeting;
    };
    return Greeter;
}());

I am confused about this part (function() { ... }());

what is the first () doing? why is the function(){} necessary? and what is the following () doing?

The syntax is pretty confusing and I hope someone can explain this.

mwen1993
  • 63
  • 4

4 Answers4

2

I am confused about this part (function() { ... }());

IIFE this function will executed as soon as it is interpreted by the browser. You don't have to explicitly call this function.

what is the first () doing? why is the function(){} necessary?

All functions in javascript are Object by nature. To create a instance of it you have to call like new Greeter() so the context this is set properly. If executed like Greeter() now the context this is from where it's executed. In most cases it's the window object.

Reference articles

https://www.phpied.com/3-ways-to-define-a-javascript-class/

https://medium.com/tech-tajawal/javascript-classes-under-the-hood-6b26d2667677

front_end_dev
  • 1,998
  • 1
  • 9
  • 14
1

That's called IIFE.

General syntax:

(function () {
    statements
})();

But sometimes, you can write:

(function () {
    statements
}());

I usually use the second's because it's following these steps:

  • Defining a function: function () { /* statements */ }

  • Calling the function: function () { /* statements */ }()

  • And wrapping the function: (function () { /* statements */ }())

Or use it with as an asynchronous thread:

(async function () {
    // await some task...
})();

(async () => {
    // await some task...
})();

You can also use it to define some local variable(s), like this:

let Person = (function () {
    let _name = null;

    class Person {
        constructor(name) {
            _name = name;
        }
        getName() {
            return _name;
        }
    }
    
    return Person;
}());

let person = new Person('Harry');
console.log(person.getName());
console.log(window._name);

For modules, you want to create some plugin(s) and make it to be global, you can write:

(function (global, factory) {
    // we can use "global" as "window" object here...
    // factory is a function, when we run it, it return "Person" class

    // try to make it global:
    global.Person = factory(); // same to: window.Person = factory();
}(window, function () {
    class Person {};

    return Person;
}));
Tân
  • 1
  • 15
  • 56
  • 102
0

This construct:

const foo = (function() { })();

Creates an anonymous function, and immediately calls it. The result gets places into foo.

It's possible to split this up in more lines with an extra variable:

const temp = function() { };
const foo = temp();

The reason typescript does this, is because placing code in function creates its own new scope. This makes it possible to do certain things without changing the global namespace.

Evert
  • 93,428
  • 18
  • 118
  • 189
0

(function() { ... }()); is a form of IIFE (Immediately Invoked Function Expression)

For example:

var Greeter = (function(){
    return 1;
}());

The result is equal to

function fn() {
    return 1;
}
var Greeter = fn();

The value of Greeter is 1 after executing the above codes. But the former one uses anonymous function and the latter one declared a variable fn to store the function.

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

This code snippet is to define a function on the prototype of object Greeter so that this function can be inherited when you create new Greeter(). You may refer to Object.prototype

Lane Yi
  • 1
  • 1