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());
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).
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.
Related
This question already has answers here:
What is the (function() { } )() construct in JavaScript?
(28 answers)
Closed 4 years ago.
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.
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
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;
}));
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.
(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
I was trying to define a function with constructor Function as below, but why the name of the function return anonymous?
let sayHi = new Function('alert("Hello")');
//this will return anonymous
sayHi.name
This happens because you are creating anonymouse function.
Named functions are initialized with:
function sayHi() {
alert('Hello');
};
sayHi.name // sayHi
...but why the name of the function return anonymous?
Because that's how the Function constructor is defined. This is covered by the spec. The Function constructor calls the abstract operation CreateDynamicFunction, which sets the name to "anonymous" near the end:
Perform SetFunctionName(F, "anonymous").
This is in contrast to a non-dynamic function with no name, which is relatively difficult to create these days because ES2015 defined that names are assigned to functions created with anonymous (!) function expressions in most situations.
The exception is assigning to a property on a pre-existing object:
const o = {};
o.foo = function() { };
console.log(o.foo.name); // ""
Just for completeness, here are some functions that use neither "" nor "anonymous" as their name:
function foo() {
}
console.log(foo.name);
const bar = function() { };
console.log(bar.name);
const baz = () => { };
console.log(baz.name);
(Yes, those second two are assigned a name as specified behavior; see this answer for details.)
Function constructor does not accept a name, therefore it is always anonymous as specified in the docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
Functions created with the syntax new Function(...) or just Function(...) create Function objects and their name is "anonymous".
(new Function).name; // "anonymous"
Hope this helps you!
I'm trying to understand the difference between 2 different function declarations in JavaScript.
Consider the following code snippet:
function SomeFunction(){
this.func1 = function(){
}
function func2(){
}
}
What is the difference between the declarations of func1 and func2 above?
In simple language,
fun1 is a property of SomeFunction class holding a reference of anonymous function where func2 is named function.
Property
Here fun1 is property of that SomeFunction class, it means when you create instance of SomeFunction class using new keyword, then only you can access it from outside.
Private Method
Here fun2 will work as private method of class SomeFunction, and will be accessible inside that class only.
Sample
function SomeFunction() {
this.func1 = function() { console.log("in func1") }
function func2() { console.log("in func2") }
}
var obj = new SomeFunction();
obj.func1(); //Accessible
obj.func2(); //Not accessible
This way of declaring functions is called Function Expression. This kind of functions can be called only after definition of the function. Function expressions load only when the interpreter reaches that line of code.
var func1 = function() {
// Code here
}
This way of declaring functions is called Function Declaration. Function declarations load before any code is executed. So it can be called anywhere in the program before it's definition. For reason, read about Hoisting in Javascript
func1 () {
// Code here
}
When defining these inside another function, Function Expression acts as the property of the function and can be accessed using the object of the parent function. Whereas, the scope of Function Declaration is inside the parent function, so it is not accessible from outside the parent function. This is a very important property in Javascript using which we can simulate the Object Oriented Nature.
In brief, Function declaration acts as Private method of a class and Function Expression as Public method.
Here is the working example below to understand more about it.
function SomeFunction(){
this.func1 = function() {
console.log('Public function.')
}
function func2() {
console.log('Private function.')
}
this.func3 = function() {
func2();
}
}
var obj = new SomeFunction();
obj.func1(); // Public Function.
// Can be accessed as it is a Public function
obj.func3(); // Private Function.
// Can be used to access a private function.
obj.func2(); // Error: Uncaught TypeError
// Private function
Hope this helps! :)
function SomeFunction() {
// Function Expression
this.func1 = function() {
}
// Function Declaration
function func2() {
}
}
Update:
Based in your question: What is the best way to declare functions within a Javascript class?
In OOP programming a Class has attributes and methods.
In the following sample code, the Person class contains:
(2) Attributes:
name
country
(1) Method:
showPerson1()
function Person(name, country) {
// Attributes of Person class.
this.name = name;
this.country = country;
// Function Expression:
this.showPerson1 = function() {
var personMessage = "Hi, my name is ";
personMessage += this.name;
personMessage += ". I'm from ";
personMessage += this.country;
personMessage += ".";
return personMessage;
};
// Function Declaration:
function showPerson2() {
var personMessage = "Hi, my name is ";
personMessage += this.name;
personMessage += ". I'm from ";
personMessage += this.country;
personMessage += ".";
return personMessage;
}
}
var person1 = new Person("John", "United States");
console.log(person1.showPerson1()); // Prints: Hi, my name is John. I'm from United States.
console.log(person1.showPerson2()); // Throws an error.
As you can see, you can execute the showPerson1() method because is reference to the Person class by using this keyword and using the Function Expression style.
However, you can't execute showPerson2() method because this function was not created like a reference to the Person class.
You can find more information here.
As far as I know your question revolves around scope. Let's say for a second that you had a main class that called upon functions from other classes. Maybe these other classes have a function called func1 that you needed to use. But wait, you want to use the name func1 in your main class as well without mentioning the global function from the other class. Using this.func1 would allow you to access it as a local function, since .this refers to a local scope.
Basically, it allows him to store the result of the function without declaring a separate variable, which is nice since it's only probably going to be used temporarily and in the context of the function in which it was declared.
Additional Reading (Or in case my analogy falls flat):
http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/
https://www.w3schools.com/js/js_function_invocation.asp
The func1 is actually a property on SomeFunction so essentially you can do
const someClass = new SomeFunction();
someClass.func1()
But you cannot do
const someClass = new SomeFunction();
someClass.func2()
because it is not attached to that class. However, you can still use the func2 internally in your class SomeFunction but not outside the class.
ES6 provides more clean syntax to understand this.
class SomeClass{
func1(){
//function body
}
}
Hope this helps
How does the new work differently in the 2 examples below? I see that the 2nd example is replacing the annoymous funciton with a variable, but in the second one, the function/class "Person" is actually being called. Does it make any difference if it's being called or not? I tried it without the calling and it still worked. So that led me to believe that new is actually calling the function and setting up this to be assigned to the instance variable.
var person = new function() {
this.setName = function(name) {
this.name = name;
}
this.sayHi = function() {
return "Hi, my name is " + this.name;
}
}
person.setName("Rafael");
console.log(person.sayHi()); // Hi, my name is Rafael
var Person = function() {
this.setName = function(name) {
this.name = name;
}
this.sayHi = function() {
return "Hi, my name is " + this.name;
}
}
var personTwo = new Person()
personTwo.setName("Rafael");
console.log(personTwo.sayHi()); // Hi, my name is Rafael
There would be almost no difference between these two examples, if it was a simple function like this:
(function() { console.log("IIFE"); })();
// or
var f = function() { console.log("Function"); };
f();
You just store your function in a variable, and then call it.
However, it makes a little difference, since it is related to JS OOP mechanisms. In the first case you get Object instance, and in the second you get Person instance. This makes difference in OOP sense.
var person = new function() { };
console.log("Is instance of: " + person.constructor.name);
console.log("There is no way to check instanceof in this case");
var Person = function() { };
var person = new Person();
console.log("Is instance of: " + person.constructor.name);
console.log(person instanceof Person);
In general, new and classes are supposed to be used as in the second case in order to enable the full functionality of JS OOP. There is absolutely no sense or/and advantage in using anonymous class constructor.
Whether or not it is assigned into a variable: does not matter. It is completely parallel to this example:
var x = 1;
console.log(x);
and
console.log(1);
Whether it needs to be called or not: A function with the new operator is always being called, but with new, parentheses are optional when no parameters are passed: new Person() is equivalent to new Person, but new Person("Joe") cannot be done differently.
In the second example, you are passing to the new operator the exact same function. You simply are using a reference (logically stored in a variable) instead of writing literal function just in place.
So, your second example is the same as:
var personTwo = new (function() {
[...]
})()
[...]
Which, in fact, is much the same as the first one:
var person = new (function() {
[...]
})
[...]
NOTE that the parentheses surrounding the function are absolutely optional in this case. You could be placed there seven if you like: (((((((function(){[...]}))))))).
The point here is that when you say «in the second one, the function/class "Person" is actually being called» you are WRONG there: That function, which acts as a constructor isn't being called by you. You are simply passing it as a parameter (the constructor function) of the new operator which is, in fact, who is actually calling the constructor with the rest of parameters you provided, if any.
See new syntax documentation:
new constructor[([arguments])]
The constructor is the function you pass to the new operator and the parameters are specified between parentheses. But they are fully optional (including the parentheses itself).
This is why new constructor; without parentheses works.
To be clear: What you thought happens (but not) would be written as:
var person = new ((function(){...})()) ();
...or, more verbosely:
var person = new (
(function(){ // Constructor builder.
[...]
return function(){...}; // Actual constructor.
})() // Constructor builder call
//v-- Parentheses to force builder to be called.
) (); // <-- Parameters (if any) passed to the constructor.
I was reading about the new JavaScript-like language from Microsoft called TypeScript. In the playground (example section), there is a simple class in TypeScript syntax converted to JavaScript code. Coming from a Java programming background, it was interesting for me to learn how OOP is done in JavaScript as compiled from TypeScript.
The TypeScript code:
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
var greeter = new Greeter("world");
var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
alert(greeter.greet())
}
document.body.appendChild(button)
And the equivalent JavaScript code:
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
alert(greeter.greet());
};
document.body.appendChild(button);
The Typescript part is very similar to Java so I understand that. Now my question is why in JavaScript the body of the Greeter class is embedded in a an anonymous function() call?
Why not write it like this?
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
What is the advantage/disadvantage of each method?
The following is called an Immediately Invoked Function Expression:
(function(){ ... })();
It is used to keep the global scope clean. Though, in this case it isn't necessary since the return value is assigned to a variable Greeter. The only time this pattern is useful is when you want "private" static members.
E.g.:
var Greeter = (function () {
var foo = 'foo', bar = 'bar'; /* only accessible from function's defined
in the local scope ... */
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
This is to allow for private members. In this example, all members are public so your two constructions are equivalent. However, if you want to provide for private members you need to hide them from the calling scope via a closure. Thus if you have a private member like so:
class Greeter {
private greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
You would probably get something like this:
var Greeter = (function () {
var greeting="";
function Greeter(message) {
greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + greeting;
};
return Greeter;
})();
The greeting variable will be available to any function defined inside the anonymous function, but invisible everywhere else.
Besides the obvious scoping/closure reasoning. Using an anonymous function that invokes itself immediately pre-loads (interprets) the class definition. This allows any JIT optimizations to be front loaded within the execution. In short, for larger more complex applications it will improve performance.
The anonymous function / self executing closure is usually used to encapsulate scope so that only the returned value is accessible outside of it. (or anything you attach to other objects, like window)
The anonymous function is probably there to prevent name collition with other parts of the code. Think of it this way, inside your anonymous function, you could even declare a variable called "$" to be whatever you want, and at the same time, be using jQuery on other parts of your code without conflict.
The closure is the sole mean to call the constructors with parameters:
var w = new Greeter("hello")
There are other methods but all complicated and with limitations and drawbacks.