Functions,Call, Apply, and Bind Functions in JavaScript ,,,,,,Inheritance ,Constructor

,Inheritance ,Constructor 

https://www.scaler.com/topics/javascript/inheritance-in-javascript/

https://dev.to/pranav016/advanced-javascript-series-part-9-constructor-functions-object-oriented-new-keyword-1gg0

JavaScript: Arrow function vs normal function explained!

https://sam-ngu.medium.com/javascript-arrow-function-vs-normal-function-explained-b755fd5ede27

5 Differences Between Arrow and Regular Functions

https://dmitripavlutin.com/differences-between-arrow-and-regular-functions/

Inheritance 












Inheritance in javascript aids a new class to have all the functionality of another class while having its own functionality as well. *The inheritance in javascript primarily involves two segments:

  • Child class: The class which inherits the properties of another class is known as the child class.
  • Parent class: The class whose property is being inherited is known as the parent class.

extends

The extends keyword is used for developing the inheritance between two classes.

The super keyword in javascript is used to call functions of an object's parent class.

  • The super() method refers to the parent class.

function is a set of instructions or procedures to perform a specific task, and

 a method is a set of instructions that are associated with an object.

A function is used to split the code into easily understandable parts, 

which can be reused as well.

Differences

Some differences between a function and method are listed below:

  • A function doesn’t need any object and is independent, while the method is a function, 

  • which is linked with any object.

  • We can directly call the function with its name, 

  • while the method is called by the object’s name.

  • Function is used to pass or return the data, 

  • while the method operates the data in a class.

  • Function is an independent functionality, 

  • while the method lies under object-oriented programming.

  • In functions, we don’t need to declare the class, 

  • while to use methods we need to declare the class.

  • Functions can only work with the provided data, 

  • while methods can access all the data provided in the given class.

 


Let's see some differences between a function and a method:

FunctionMethod
Functions have independent existence. You can define them outside of the class.Methods do not have independent existence. They are always defined within a class, struct, or enum.
Functions are the properties of structured languages like C, C++, Pascal and object based language like JavaScript.
Note: There is no concept of function in Java.
Methods are the properties of Object-oriented language like C#, Java, Swift etc.
Functions don't have any reference variables.Methods are called using reference variables.
Functions are a self describing piece of code.Methods are used to manipulate instance variable of a class.
Functions are called independently.Methods are called using instance or object.


Advantages of using Arrow Function: The following points will describe the list of advantages which are associated with using Arrow functions instead of normal functions –

  • This arrow function reduces lots of code and makes the code more readable.
  • Arrow function syntax automatically binds “this” to the surrounding code’s context.
  • Writing the arrow => is more flexible as compared with the writing function keyword.

When one should use the Arrow function: Since in previous sections, we have discussed the syntax, advantages, and flexibility associated with the arrow function syntax, here we will see and analyze when and when we should use arrow functions instead of normal functions.

  • We may use arrow function syntax with our method associated with the array, like map(), reduce(), filter() since by using arrow function syntax instead of using normal function syntax one could easily read and understand as well as write the code more effectively.
  • If we may use arrow functions while declaring promises and callbacks then it would be much easier for any user to understand the concept behind them otherwise by using traditional function syntax concepts like callback hells, promise chaining would eventually become more difficult to understand, or even writing would become a little complex.
  • Limitations of using Arrow functions: Following are the certain limitations of using an arrow function:

    • An arrow function doesn’t have its own bindings with this or super.
    • An Arrow function should not be used as methods.
    • An arrow function can not be used as constructors.
    • An arrow function can not use yield within its body.
    • Arrow function cannot be suitable for call apply and bind methods.

    • The this keyword refers to an object. Which object depends on how this is being invoked (used or called). The this keyword refers to different objects depending on how it is used.

      • In an object method, this refers to the object.
      • Alone, this refers to the global object.
      • In a function, this refers to the global object.
      • In a function, in strict mode, this is undefined.
      • In an event, this refers to the element that received the event.
      • Methods like call()apply(), and bind() can refer this to any object.

Difference between call,apply and bind

In Object Oriented JavaScript, everything is an object and therefore we can set and access additional properties to functions and methods via the prototype



Call( ): The call() method invokes a function with a given 'this' value and arguments provided one by one. This means that we can call any function, and explicitly specify what 'this' should reference within the calling function.



Alt Text



Apply( ): Invokes the function and allows you to pass in arguments as an array.



Alt Text


Bind(): returns a new function, allowing you to pass in an array and any number of arguments.


Alt Text

When we use the bind() method:

1.The JS engine is creating a new invite instance and binding friend1 and friend2 as its 'this' variable. So basically it copies the invite function.

2.After creating a copy of the invite function it is able to call inviteFriend1( ) and inviteFriend2( ), although it wasn’t on the friend1 and friend2 object initially. It will now recognizes its properties and its methods.

Call and apply are pretty interchangeable. Both execute the current function immediately. You need to decide whether it’s easier to send in an array or a comma separated list of arguments. Whereas Bind creates a new function that will have this set to the first parameter passed to bind().

Defining Functions

A set of statements that performs a certain task or calculates a value.
A function should take some input and return an output where there is some obvious relationship between the input and the output.

Function Declaration

  • Name of the function.
  • A list of parameters to the function, enclosed in parentheses and separated by commas.
  • The JavaScript statements that define the function, enclosed in curly brackets{...}.

This is a simple function named square, which will return the square of the given number .

  1. The function square takes one parameter, called num.
  2. The function consists of one statement that returnthe parameter of the function (that is, num) multiplied by itself.

Hope you Understood, the basic concept of function now.

Types of functions in javascript?

  1. Named function
  2. Anonymous function
  3. Immediately invoked function expression. It runs as soon as the browser finds it.

Named function

Named function is the function that we define it in the code and then call it whenever we need it by referencing its name and passing some arguments to it. Named functions are useful if we need to call a function many times to pass different values to it or run it several times.

Here is an example:

Anonymous function

The anonymous functions don’t have names. They need to be tied to something: variable or an event to run.

The same function from above but with anonymous function:

Immediately invoked function expression—

IIFE

Invoked function expression runs as soon as the browser encounters it. The benefit of this function is that it runs immediately where it’s located in the code and produces a direct output. That means it is unaffected by code which appears further down in the script which can be useful.

An invoked function expression is great for quickly populating a variable or argument in a larger function or a property in an object and are often hooked to event listeners for immediate output.

Definitions




Let's look at the functions we'll be studying here a bit more closely to understand what they do.

Call is a function that helps you change the context of the invoking function. In layperson's terms, it helps you replace the value of this inside a function with whatever value you want.

Apply is very similar to the call function. The only difference is that in apply you can pass an array as an argument list.

Bind is a function that helps you create another function that you can execute later with the new context of this that is provided.

Now we will look at some basic examples of the call, apply, and bind functions. Then we will look at an example were we will be constructing our own function similar to the map function.

How to Use the Call Function in JavaScript

call is a function that you use to change the value of this inside a function and execute it with the arguments provided.

Here is the syntax of the call function:


func.call(thisObj, args1, args2, ...)

Where,

  • func is a function that needs to be invoked with a different this object
  • thisObj is an object or a value that needs to be replaced with the this keyword present inside the function func
  • args1, args2 are arguments that are passed to the invoking function with the changed this object.

Note that if you invoke a function without any thisObj argument, then JavaScript considers this property to be a global object.

Now that we have some context around what the call function is, let's start off by understanding it in more detail with some examples.

How to call a function with different contexts in JS

Consider the below example. It consists of 3 classes – CarBrand1, and Brand2.

function Car(type, fuelType){
	this.type = type;
	this.fuelType = fuelType;
}

function setBrand(brand){
	Car.call(this, "convertible", "petrol");
	this.brand = brand;
	console.log(`Car details = `, this);
}

function definePrice(price){
	Car.call(this, "convertible", "diesel");
	this.price = price;
	console.log(`Car details = `, this);
}

const newBrand = new setBrand('Brand1');
const newCarPrice = new definePrice(100000);

If you look carefully, you can see that we use the call function to invoke the Car function on two occasions. Firstly, in the setBrand and then in the definePrice functions.

In both of these functions, we invoke the Car function with this object representing to the respective functions themselves. For example, inside setBrand, we call the Car function with the this object belonging to its context. The case is similar for definePrice.

How to call a function with no arguments in JS

Consider the below example:

const newEntity = (obj) => console.log(obj);

function mountEntity(){
	this.entity = newEntity;
	console.log(`Entity ${this.entity} is mounted on ${this}`);
}

mountEntity.call();

In this example, we invoked the function mountEntity with no thisObj argument. In such cases, JavaScript refers to the global object.

How to Use the Apply Function in JavaScript

The Apply function is very similar to the Call function. The only difference between call and apply is the difference in how arguments are passed.

In apply, arguments you can pass an argument as an array literal or a new array object.

Here is the syntax for the apply function:

func.apply(thisObj, argumentsArray);

Where,

  • func is a function that needs to be invoked with a different this object
  • thisObj is an object or a value that needs to be replaced with the this keyword present inside the function func
  • argumentsArray can be an array of arguments, array object, or the arguments keyword itself.

As you can see above, the apply function has different types of syntaxes.

The first syntax is a simple one. You can pass in an array of arguments like below:

func.apply(thisObj, [args1, args2, ...]);

The second syntax is where we can pass in the new array object to it:

func.apply(thisObj, new Array(args1, args2));

The third syntax is where we can pass in the arguments keyword:

func.apply(thisObj, arguments); 

arguments is a special object available inside a function. It contains values of the arguments that are passed to a function. You can use this keyword with the apply function to take any number of arbitrary arguments.

The best part about apply is we don’t need to take care of the number of arguments that are passed to the invoking function. Because of its dynamic and versatile nature, you can use it in complicated situations.

Let’s look at the same example as above, but this time we'll use the apply function.

function Car(type, fuelType){
	this.type = type;
	this.fuelType = fuelType;
}

function setBrand(brand){
	Car.apply(this, ["convertible", "petrol"]); //Syntax with array literal
	this.brand = brand;
	console.log(`Car details = `, this);
}

function definePrice(price){
	Car.apply(this, new Array("convertible", "diesel")); //Syntax with array object construction
	this.price = price;
	console.log(`Car details = `, this);
}

const newBrand = new setBrand('Brand1');
const newCarPrice = new definePrice(100000);

And here is an example that showcases how you'd use the arguments keyword:

function addUp(){
		//Using arguments to capture the arbitrary number of inputs
    const args = Array.from(arguments); 
    this.x = args.reduce((prev, curr) => prev + curr, 0);
    console.log("this.x = ", this.x);
}

function driverFunc(){
    const obj = {
        inps: [1,2,3,4,5,6]
    }
    addUp.apply(obj, obj.inps);
}

driverFunc();

How to Use the Bind Function in JavaScript

The bind function creates a copy of a function with a new value to the this present inside the calling function.

Here is the syntax for the bind function:

func.bind(thisObj, arg1, arg2, ..., argN);

Where,

  • func is a function that needs to be invoked with a different this object
  • thisObj is an object or a value that needs to be replaced with the this keyword present inside the function func
  • arg1, arg2…argN – you can pass 1 argument to the calling function or more than that, similar to the call function.

The bind function then returns a new function that consists of a new context to the this variable present inside the calling function:

func(arg1, arg2);

Now this function func can be executed later with the arguments.

Let's look at a classic example of how to use a bind function with the help of a class-based React component:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 1
    };
  }
  handleCode() {
    console.log("HANDLE CODE THIS = ", this.state);
  }
  render() {
    return <button onClick={this.handleCode}>Click Me</button>;
  }
}

Consider the above App component. It constitutes the following things:

  • constructor is a function that gets called a class and is instantiated with a new keyword.
  • render is a function that executes/renders the JSX code.
  • handleCode is a class method that logs the state of the component.

If we click on the Click Me button then we will receive an error stating: Cannot read properties of undefined (reading 'state').

Have you ever wondered why this issue occurs? 🤔🤔

You might be expecting that we should be able to access the state of the class since handleCode is a class method. But here is the catch:

  • this inside the handleCode is not same as that of the class’s this.
  • Inside a class, this is a regular object that has non-static class methods as its properties. But this inside the handleCode will refer to a different context.
  • To be honest, the value of this in this scenario depends on from where the functions is being called. If you see, the handleCode is being called on onClick event.
  • But at this stage, we will get undefined for the context of this present inside the handleCode function.
  • We're trying to call the state property of an undefined value. Therefore, this leads to the above error.

We can fix this by providing the right context of this inside the handleCode method. You can do this with the bind method.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 1
    };
   this.handleCode = this.handleCode.bind(this); //bind this function
  }
  handleCode() {
    console.log("HANDLE CODE THIS = ", this.state);
  }
  render() {
    return <button onClick={this.handleCode}>Click Me</button>;
  }
}

The bind will create a new function and store it inside the this object with a new property as handleCodeBind will make sure that the class’s this context gets applied to the this present inside the handleCode function.

How to Create Your Own map Function

Now that we have all the necessary things, let's start off by creating our own map function. Let's first understand the things that we will need to build our own map function.

Here is the syntax of the map function:

arr.map(func)

Where,

  • arr is an array on which the map is called.
  • func is the function that needs to run on each element of an array.

The basic functionality of a map function is simple:

It is a function that walks through each element of an array and applies the function that is passed as an argument. The return type of a map is again an array with func being applied on each element.

Now we understand the requirements, so we can move on to create our own map function. Here is the code of our new map function:

function newMap(func){
  let destArr = [];
  const srcArrLen = this.length;
  for(let i = 0; i < srcArrLen; i++){
    destArr.push(func.call(this, this[i]));
  }

  return destArr;
} 

Let's understand the above function bit-by-bit:

  • This function accepts an argument called func. It's nothing but a function that needs to be called on each element of an array.
  • The other parts of the code are pretty self explanatory. We will focus on the following line: destArr.push(func.call(this, this[i]));
  • This line does two things:
    1. Pushes the changes into the destArr
    2. Executes the func with the help of call method. Here the call method (as explained in the previous sections) will execute the func method with a new value to the this object present inside the func method.

Now let's take a look at how we are going to execute our newMap function. The below approach of adding a new method to the existing primitive data type is not recommended but still we will do it for the sake of this article.

NOTE: do not follow the below approach in your production code. This can cause damage to the existing code.

Object.defineProperty(Array.prototype, 'newMap', {
  value: newMap
}); 

defineProperty we create a new property inside the Array.prototype.

Once this is done, we are good to go with executing our new map function on an array.

const arr = [1,2,3];
const newArr = arr.newMap(item => item + 1);
console.log(newArr);

Summary

This article showed you what the call, apply, and bind functions can do via examples.

https://dev.to/pranav016/advanced-javascript-series-part-5-iife-this-keyword-in-jstricky-eg-call-apply-bind-curryingfunctional-prog-98c

IIFE

An IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined.

Use cases-

Helps avoid polluting the global namespace-

  • Since our application may incorporate a large number of functions and global variables from various source files, it's critical to keep the number of global variables to a minimum.
  • We could utilize the IIFE pattern if we have some initiation code that we don't need to use again. Because we won't be reusing the code, IIFE is preferable than a function declaration or a function expression in this scenario.

Example-

(function () {
  // some initiation code
  let firstVariable;
  let secondVariable;
})();

firstVariable and secondVariable will be discarded after the function is executed.

IIFE

The module pattern-

  • We would also use IIFE to create private and public variables and methods.
  • These patterns were more useful before the introduction of ES6, when we didn't have the let and the const keywords. Back then when we imported all the JavaScript files into one, then there were a lot of conflicts in variable names since all variables were global because of declaration using var. Thus developers used IIFE module patterns where the variables were made and only those required inside module were left in global scope and others were discarded because of property of Scope using IIFEs. This also overlaps with the first use case of IIFEs mentioned above. Consider this example to understand better-
Example-

As you know that a function in JavaScript creates the local scope. So, you can define variables and function inside a function which cannot be access outside of that function. However, sometime you accidently pollute the global variables or functions by unknowingly giving same name to variables & functions as global variable & function names.

For example, there are multiple .js files in your application written by multiple developers over a period of time. Single JavaScript file includes many functions and so these multiple .js files will result in large number of functions. There is a good chance of having same name of function exists in different .js files written by multiple developer and if these files included in a single web page then it will pollute the global scope by having two or more function or variables with the same name.

Consider the following example of MyScript1.js and MyScript2.js with same variable & function name.

MyScript1.js
var userName = "Bill";

function display(name)
{
    alert("MyScript1.js: " + name);
}

display(userName);
MyScript2.js
var userName = "Steve";

function display(name)
{
    alert("MyScript2.js: " + name);
}

display(userName);
Importing both files-
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>JavaScript Demo</title>
    <script src="/MyScript1.js"></<script> 
    <script src="/MyScript2.js"></<script> 
</head>
<body>
    <h1> IIFE Demo</h1>
</body>
</html>

If you run above example, you will find that every time it call display() function in MyScript2.js because MyScript2.js included after MyScript1.js in a web page. So JavaScript considers last definition of a function if two functions have the same name.

IEFE solves this problem by having its own scope and restricting functions and variables to become global. The functions and variables declare inside IIFE will not pollute global scope even they have same name as global variables & functions. So let's see what is an IIFE is.

Advantages of IIFE:

  • Helps avoid creating unnecessary global variables and functions.
  • Functions and variables defined in IIFE do not conflict with other functions & variables even if they have same name.
  • Organize JavaScript code.
  • Make JavaScript code maintainable.

  • Even though the information above is more than enough and well explained to grasp the concept but you can still check out this documentation and this article to read more in-depth about IIFEs.*


this keyword-

this represents the object that the function is a property of.

or simply

this helps refer to the object it belongs to.

  • In a method, this refers to the owner object.

Example-

Code-

const person = {
  firstName: "Pranav",
  lastName : "Mendiratta",
  fullName : function() {
    // here `this` keyword refers to our object `person` 
    return this.firstName + " " + this.lastName;
  }
};
console.log(person.fullName())

Output-

"Pranav Mendiratta"
  • Alone, this refers to the global object (called the window object in the browser).

Example-

Code-

console.log(this)

Output-

window
  • In a function, this refers to the global object.
  • In a function, in strict mode, this is undefined.
  • In an event, this refers to the element that received the event.

Example-

Code-

<button onclick="this.style.display='none'">
  Click to Remove Me!
</button>

Tricky example on this keyword 1

Output-

window
window
c

Explanation-

  • Both a and b are functions of the global/ window object, thus as per the definition, the window object gets returned.

this represents the object that the function is a property of.

  • The third console.log returns the c object because that's what has called the hi() function in c.hi().

  • One trick to solve these easily is to check what is on the left side of the function call. If there is nothing then it returns the window object. If some object is calling it like c.hi() then the this keyword in the function points to the object c.

Tricky example on this keyword 2

Output-

obj
window

Explanation-

  • On calling the sing() function, the console.log(this) on line 4 returns the obj object since obj is calling the function.
  • Whereas the console.log(this) on line 6 returns the window object because its function call is not attached to any object, and those not attached are always under the global/ window object.

Tricky example on this keyword 3

Output-

b
window
d

Explanation-

  • Using the trick we learned in tricky example 1, we see that b.say() should return the b object and it does exactly that.
  • Arrow functions are lexically scoped where as regular anonymous functions are dynamically scoped.
  • That is why when calling c.say()(), it returns the window object because it uses anonymous functions that are lexically scoped (we've learned in earlier part of the series). > Lexical scope care where a function was declared, but dynamic scope cares where a function was called from.
  • This statement will help in understanding the difference.
  • The final output on calling d.say()() returns the object d that is the correct output because it used the arrow functions that are dynamically scoped and bind the this keyword with the object calling the function.

Tricky example on this keyword 4

const phone = function (model, brand){
  this.model = model,
  this.brand = brand
}

// regular anonymous  function used
phone.prototype.clickPicture = function(){
  console.log(`${this.brand} ${this.model} clicks picture!`)
}

// arrow function used here
phone.prototype.powerOn = () => {
  console.log(`${this.brand} ${this.model} boots up!`)
}

const iphone = new phone("Iphone 12", "Apple")
console.log(iphone.clickPicture())
console.log(iphone.powerOn())

Output-

"Apple Iphone 12 clicks picture!"
"undefined undefined boots up!"

Explanation-

  • Arrow functions are lexically scoped where as regular anonymous functions are dynamically scoped that is why the arrow functions that are dynamically scoped and bind the this keyword with the object calling the function and the other function doesn't thus logging undefined on using this.brand or this.model.

Conclusion-

  • A lot of the weird behavior of the this keyword is mainly because it is dynamically scoped and not lexically scoped like everything else in JavaScript meaning that it is not important where it is written but how it is called.

Solution to weird behavior-

  • One way to solve these issues is the use of arrow functions that were introduced in ES6.
  • If we use an arrow function in the previous example then our function gives us the desired output.
  • Another way is to bind the this keyword to the object. We will learn more about bind keyword ahead.

This
Credits- Iqbal M Ipel


Function
Credits- Sanjeev Sharma

call()

With the call() method, you can write a method that can be used on different objects.

Example-

Code-

const wizard = {
  name: 'Pranav',
  health: 100,
  heal: function(num1, num2) {
    this.health += num1 + num2;
  }
}

const archer = {
  name: 'Robin',
  health: 50
}

wizard.heal.call(archer, 50, 60)
console.log(archer)

Output-

{
  health: 160,
  name: "Robin"
}

apply()

With the apply() method, you can write a method that can be used on different objects.

  • It is very similar to the call keyword, only difference is that the arguments are passed as an array when we are using apply.

Example-

Code-

const wizard = {
  name: 'Pranav',
  health: 100,
  heal: function(num1, num2) {
    this.health += num1 + num2;
  }
}

const archer = {
  name: 'Robin',
  health: 50
}

wizard.heal.apply(archer, [20, 30])
console.log(archer)

Output-

{
  health: 100,
  name: "Robin"
}

bind()

The bind() method creates a new function that, when called, has its this keyword set to the provided value.

  • It let’s us explicitly define the value of this when calling a function.

  • It returns a new function that we can call.

Example-

Code-

const wizard = {
  name: 'Pranav',
  health: 100,
  heal: function(num1, num2) {
    this.health += num1 + num2;
  }
}

const archer = {
  name: 'Robin',
  health: 50
}

const healArcher = wizard.heal.bind(archer, 50, 60);
healArcher()
console.log(archer)

The js engine is creating a new instance of the heal function and binding its this object to archer.

Output-

{
  health: 160,
  name: "Robin"
}

CallApply
Credits- Himanshu Satija


Currying-

Currying is a technique of evaluating function with multiple arguments, into sequence of functions with single argument.

Example 1-

Code-

function volume(length) {
      return function(width) {
         return function(height) {
            return height * width * length;
         }
      }
   }
console.log(volume(11)(2)(3))

Output-

66

Example 2-

Code-

function sum(a, b) {
    return a+b;
}

var sumWithThree = sum.bind(this, 3);
console.log(sumWithThree(4));

Output-

7

Partial Application-

Partial application starts with a function. We take this function and create a new one with one or more of its arguments already “set” or partially applied. It will help reduce the number of parameters needed for our functions.

  • Both currying and partial application are patterns that allow us to call functions with some of their parameters, and provide the rest later.

  • They both are important concepts in Functional programming.

Example-

Code-

const multiply = (a, b, c) => a * b * c
const partialMultiplyBy5 = multiply.bind(null, 5)
partialMultiplyBy5(10, 20)

Output-

1000

Difference b/w Currying and Partial Application-

  • Partial application is more or less a pattern of calling a function. You can partially apply any function.
  • Currying is more about a form of the function. To be able to use currying, you have to explicitly create a new function that is a curried version of the original one.

Advantages of using Currying or Partial Application-

  • They both help us create specialized versions of generic functions, thus removing duplication and making the code easier to compose.
  • Another benefit of using partial application and currying is that they can help us create more readable code.

Comments