Know Your JavaScript🤌
Published: 2022-09-12 18:52:11

---
title: Know Your JavaScript🤌
published: true
date: 2022-08-24 12:20:02 UTC
tags: 
canonical_url: https://blog.sagarmedtiya.me/know-your-javascript
---
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ezf6mymb62ijra2xcj5o.gif)
This blog covers the basics of JavaScript. So, lets begin

## 🔭Scope

Scope in JavaScript defines accessibility of variables, objects and functions. There are three types of scope:

- Global Scope

When the JavaScript engine executes a script, it creates a global execution context. When we define global-scoped variable then that variable can be accessible through out the script.

```
var message = 'Hi';

```

![JavaScript-Global-Variables.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660903195045/8Defyz2cj.png)_Image Source: javascripttutorial.net/_

The variable message is global-scoped. It can be accessible everywhere in the script.

- Local Scope

The variable which is defined inside the function is called local variable and can only be accessible inside the function.

```
function animal(){
    let animal1 = 'tiger';
    console.log(animal1);
}
animal();
console.log(animal1);

```

**Output:**

![Screenshot 2022-08-19 160323.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660906122874/YTOZJb9XU.png)

In the above code, the variable `animal1`, when calling outside the function is returning referenceError as the variable is defined inside the function.

- Block Scope

Generally, whenever you see curly brackets {}, it is a block. It can be the area within the `if`, `else`, `switch` conditions or `for`, `do while`, and `while` loops.

## Hoisting

By the definition of MDN,

> JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code.

It allows functions to be safely used in code before they are declared.

For example,

```
console.log(Hoist);
var Hoist = 'The variable Has been hoisted'; //Output: undefined

```

JavaScript only hoists declarations, not initialization. Functions are hoisted first and then variables. Variables and constants declared with let and const are not hoisted. Function declaration are hoisted but function expressions are not.

## Polymorphism

Polymoriphism in javascript refers to the concept of reusing a single piece of code multiple times.

For example,

```
class Car{
    constructor(vehicle){
        this._vehicle = vehicle;
    }
    move(){
        console.log('drive', this._vehicle);
    }
}
class Bike{
    constructor(vehicle){
        this._vehicle = vehicle;
    }
    move(){
        console.log('ride', this._vehicle);
    }
}
function getVehicle(vehicle){
    switch(vehicle.type){
        case"bike":
            return new Bike(vehicle);
        case "car":
            return new Car(vehicle);
        default:
            break;
    }
}

let vehicle = getVehicle({
    type: "bike",
});
vehicle.move() // ride {type:'bike'}
vehicle = getVehicle({
    type: 'car',
})
vehicle.move(); // drive {type:'car}

```

**Ouput:**

![Screenshot 2022-08-19 185027.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660915241300/ZOKF_3b-8.png)

In the above code, both are 🚜vehicles and both vehicles move. But depending on the type of the vehicle, they move differently. But from the user's point of view they just have to call `move()` method.

## Closures

> Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.

In laymen terms, whenever you see a function keyword within another function, the inner function has access to variables in the outer function, that is a closures.

```
var a = 42;
function js(){
  return a;
}
js()

```

This is the example of closure because `a` is outside the scope of `function js()`. Closures are just using variables that come from a higher scope.

### Closure remembers the environment

The function defined in the closure 'remembers' the environment in which it was created. Closure happens when an inner function is defined in outer function and is made accessible to be called later.

```
function fruit(){
    var apple = 'Hello apple';
    var log = ()=>{
        console.log(apple);
    }
    return log;
}
var closure = fruit();
closure();

```

**Output:**

![Screenshot 2022-08-22 003346.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661108676075/3TG1IdoZd.png)

In the above code, `closure`variable is now pointing to the `log()` function. Meaning calling `closure()` function is actually invoking the `log()` function from the `fruit()` function. If you see result `log()` functions accurately logs the value of `hello` variable which was originally declared in the parent function `fruit()`. It means the `log()` function has accurately "remembered" the value of the `hello` variable.

## IIFE

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

For example,

```
(function fruit(){
    //your code here
})()

```

It is a function expression. It is moreover a self-executing function and useful in closure. It also prevents from polluting the global scope.

```
var sum = (function(){
    var foo = 20;
    function bar(){
        foo = foo +10;
        console.log(foo);
    }
    return bar;
})()
sum()   
sum()
sum()

```

**Output:**

![Screenshot 2022-08-22 103403.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661145229324/9mF0oUOe0.png)The primary reason to use an IIFE is to obtain data privacy. Because JavaScripts var scopes variables to their containing function, any variables declared within the IIFE cannot be accessed by the outside world.

## `new` and `this` keywords

The `new` operator will create the instance of an object. If the `new` keyword is called then the following actions are taken:

- It links the newly created object to another object. It does it by setting its constructor to another object. The object type is set to its constructor function.
- It makes the `this` variable point to the newly created object.
- It invokes the constructor function.
- `object.prototype` property is set to the object's prototype. For example,

```
function Car(name){
    console.log(this); //this points to myCar
    this.name = name;
}

var myCar = new Car('honda')
console.log(myCar)

```

**Output:**![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661236909086/24yC4OzRk.png)For more insights,

`Car` is a constructor function because it is invoked using `new` keyword. `Car` function has a field called `name`. `myCar` object is created from the `Car` function using `new` keyword. It makes `Car` the prototype/constructor of `myCar`. It sets the `name` field to `Honda`. The value of `myCar` becomes `{name: "Honda"}`

## Prototype

Prototype is a link to another object. In JavaScript, objects are chained together by prototype chain. JS objects inherit properties and methods from a prototype. Prototype property allows you to add properties and methods to any object dynamically.

For example,

```
function Animal(name){
    this.name = name;
}
Animal.prototype.age =10;
var Cat = new Animal('cat');
console.log(Cat)
console.log(Cat.name)
console.log(Cat.age)

```

**Output:**

![Screenshot 2022-08-23 135918.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661243396455/BAs4Rxd-d.png)

When object `Cat` is inherited from object `Animal`, then `Animal` is the prototype object or the constructor of the `Cat`.

## Prototypal Inheritance

Prototypal Inheritance means that if the property is not found in the original object itself then the property will be searched for in the object's parent prototype object.

For example,

```
function Animal(name){
    this.name = name;
}
Animal.prototype.move=function(){
    console.log('move');
}
Cat.prototype = Object.create(Animal.prototype)
function Cat(name){
    Animal.call(this,name);
}

Cat.prototype.meow=function(){
    console.log('meow');
}

var misty = new Cat('misty');
console.log(misty);
console.log(misty.name);
console.log( misty.meow());
console.log( misty.move())

```

**Output:**

![Screenshot 2022-08-23 170716.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661264968281/oB_Q6iyjx.png)

`Animal` object is at the top of the inheritance. It has a `Animal.prototype` property on it. We also have `Cat` object and to execute prototypal inheritance we have to link their `prototype`. `Cat.prototype` is linked with `Animal.prototype`. Then we have created `misty` object from `Cat`.

### Why prototypal inheritance is better?

- It is simple, just create and extend objects. You don't worry about classes, interfaces, abstract classes, virtual base classes, constructor etc.
- It is more powerful, you can 'mimic' multiple inheritance by extending object from multiple objects. Just handpick properties and methods from the prototypes you want.
- It is dynamic, you can add new properties to prototypes after they are created. This also auto-adds those properties and methods to those object which are inherited from this prototype.
- It is less verbose than class-based inheritance.

## Memoization

> Memoization is a technique for speeding up the application by caching its previously computed results. If the data is not cached, then the function is executed, and the result is added to the cache.

The function is an integral part of the programming, they help to modularity and reusable to our code, as per above definition memoization is an optimizing our code.

```
const memoizedAdd = () => {
    let cache = {};
    return (value) => {
        if (value in cache) {
            console.log('Fetching from cache');
            return cache[value];
        } else {
            console.log('Calculating result');
            let result = value + 10;
            cache[value] = result;
            return result;
        }
    }
}
// returned function from memoizedAdd
const newAdd = memoizedAdd();
console.log(newAdd(9)); //output: 19 calculated
console.log(newAdd(9)); //output: 19 cached

```

**Output**

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661283807560/VZxeoMMyg.png)

## apply, call and bind methods

`apply`, `call` and `bind` are used to attach a correct `this` to the function and invoke it. The difference is the way of function invocation.

**bind()**

It returns a function. This returned function can later be called with a certain context set for calling the original function. The returned function needs to be invoked separately.

For example,

```
var person ={
    hello: function(message){
        console.log(this.name + " says hello "+ message)
    }
}
var ngNinja = {
    name: "NgNinja Academy"
}
var sayHello = person.hello.bind(ngNinja)
sayHello("world");

```

**Output:**![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661325158637/hc1TCKpjG.png)Here, `person` object has a method called `hello()`. `ngNinja` object does not have it. You can bind `hello()` to `ngNinja` object and call it later in the code.

**call()**

`call()` attaches this to function and invokes the function immediately. The owner object is sent as an argument. With `call()`, an object can use a method belonging to another object.

For example,

```
var person ={
    hello: function(message){
        console.log(this.name + " says hello "+ message)
    }
}
var ngNinja = {
    name: "NgNinja Academy"
}
person.hello.call(ngNinja,"world");

```

**Output**![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661325534799/2bTb7KPvD.png)

In the above example `this` is set to the `ngNinja` object. You can send arguments to the function as a comma-separated list following the owner object.

**apply()**

`apply()` also attaches this to a function and invokes the function immediately. `apply()` is similar to `call()` except it takes an array of arguments instead of the comma-separated list.

For example,

```
var person ={
    hello: function(message){
        console.log(this.name + " says hello "+ message)
    }
}
var ngNinja = {
    name: "NgNinja Academy"
}
person.hello.apply(ngNinja,["world"]);

```

**Output**

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661326027288/pFcyYVm8C.png)

Here, this is set to the ngNinja object. You can send arguments to the function as a comma-separated list following the owner object.

## Callback Function

Callback functions are executed "later". Later it can be any action that you'd want to be completed before calling the callback function. Callback functions are passed as arguments to the outer function.

For example,

```
function getName(){
    return "viewers";
}
function greet(getName){
    const name = getName();
    return "Hello " + name;
}
greet(getName);

```

**Output**

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661327711852/sjRTkYER8.png)In the above code, we can see that we are passing the function which we want to execute later on. `greet()` is the outer function. And `getName()` is the callback function. We pass `getName()` function to the outer `greet()` function as a function argument. The value from `getName()` callback function is then used in the outer function `greet()`.

## Promises

For detailed explanation of the promise, you can read the other blog. [Promises](https://dev.to/sagarmedtiya/understanding-promises-in-javascript-11id-temp-slug-9874661). Thank you 🧡

## Asynchronous Js

In JavaScript Synchronous and asynchronous are code execution Pattern,

In JavaScript Code Execution done By two separate ways:

1. Browser JS Engine (popular V8 JS Engine)
2. NodeJs V8 Engine

**Browser JS** Engine parse Html file and executes JavaScript by three patterns,

1. synchronous
2. Asynchronous
3. defer

```
index.html

<script src='index.js'> //default Synchronous

<script async src='index.js'> //parse as Asynchronously

<script defer src='index.js'> //parse as deferred

```

**NodeJS V8 Engine:** NodeJS V8 engine executes its JavaScript Code as single-threaded based on the Event loop!

## async and await

`async` makes a function return a Promise and `await` makes a function wait for a Promise. Similar to callback and promises, we have another paradigm for handling async programming. Every async function you write will return a promise, and every single thing you await will ordinarily be a promise.

In JavaScript Asynchronous pattern handled in various versions,

> ES5 -> Callback
> 
> ES6 -> Promise
> 
> ES7 -> async & await For example,

```
let promise1 = new Promise((resolve, reject)=>{
    console.log("Hello");
})
let promise2 = new Promise((resolve,reject)=>{
    resolve(setTimeout(()=>{
        console.log('viewers')
    },5000))
})

async function display() {
    let data = await Promise.all([promise1,promise2]);
    console.log(data);
  }

display()

```

**Output**

![Screenshot 2022-08-24 163246.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661340215605/jQbaC3P2_.png)

In the above code, we have used two promises and used `display()` function with `async` and `await`. In Async & Await lot more stuff there, Just play around it. ![Thank you](https://docs.google.com/uc?export=download&id=166Ecq6uBl61U14OUlkHOHIBv2ArKoumJ)

Here JavaScript API cheatsheet for front end developer http://overapi.com/javascript

![Screenshot 2022-08-24 165509.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1661341225019/k9Z5JX1Yx.png)_Image source: http://overapi.com/javascript_

Thanks for reading, if you like it you can subscribe to my blog. 🧡

References from:

- https://developer.mozilla.org/
- https://hackernoon.com/