Reputation: 455
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
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
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