user3760959
user3760959

Reputation: 455

What is this code's constructor doing?

I'm not getting what's happening in the below code. Why constructor function is enclosed inside another function and why both constructor and the function in which it is enclosed have given the same name? Also why enclosing function has made to be self invoked?

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

Upvotes: 0

Views: 301

Answers (2)

Ravindra Thorat
Ravindra Thorat

Reputation: 2002

You can consider the self-invocation function as kind of higher order function, that returns some another function with some configuration.

Okay, what that self-invocation function is doing? It does contain one constructor functions which hold one public property with name "greeting". Input parameter received from constructor function, get assigned to the greeting. After this signature, it's adding some helper function to this constructor function, with the help of prototype, which prints greeting message.

what does it mean by prototype? it's the one of the major pillar of javascript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

Well! do we really need a self-invocation function for this? the answer is, nope! we can have this written in a simple way too, just like below,

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

var greeter;
greeter = new Greeter("world");
console.log(greeter.greet());

That's it! And it will give the exact result as above.

Then why that guy used the self-invocation function for it? I believe, cool design pattern always shines. That guy has a plan to write some factory function kind of thing which would give me a fully configured constructor function. In this case, the self-invocation expression is nothing but the so called factory.

Note: in the original post by you, the outer most Greeter is not a real function, that is a simple variable which holds some function, returned by that self invocation block. You can use any name for that variable.

Upvotes: 2

Nickolay
Nickolay

Reputation: 32081

In this particular case there's no point in wrapping Greeter in an immediately invoked function (IIFE); Ravindra Thorat is right that rewriting results in (mostly) equivalent behavior.

This construct starts to make sense when you put more stuff inside the anonymous-immediately-executed-function, like the strict mode marker or a private variable (GREETING in example below):

var Greeter = (function () {
    "use strict";
    const GREETING = "Hello, ";

    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return GREETING + this.greeting;
    };
    return Greeter;
}());
var greeter;
greeter = new Greeter("world");
console.log(greeter.greet());
// console.log(GREETING) // not defined here -- only available inside the anonymous function

Updated to answer a comment:

Note that the value of the outermost variable Greeter is not the outer anonymous (nameless) function itself, but the result of its invocation. Compare:

var Greeter = (function() {...})() // the returned value is assigned to Greeter
var Greeter = (function() {...})   // the anonymous function without parameters is assigned to Greeter

Since the outer anonymous function ends with return Greeter, the value of the outermost Greeter variable is the function Greeter(message) declared inside the IIFE.

Basically everything inside the IIFE is unavailable outside it, except the explicitly returned object (the Greeter(message) constructor in this example).

Upvotes: 2

Related Questions