> For the complete documentation index, see [llms.txt](https://ricardomol.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ricardomol.gitbook.io/notes/frontend/untitled.md).

# Javascript

## Key features

* **Interpreted** language
* No multithreading or multiprocess capabilities
* Case-sensitive

## **Hoisting**

Variables declared or initialized with the `var` keyword will have their **declaration "moved" up** to the top of the current scope.

## null vs undefined

Two distinct values for nothing: null and undefined.

### **undefined**

Means: value of the variable is not defined.

Global variable `undefined` whose value is "undefined"

`typeof undefined` is also "undefined"

undefined is not a constant or a keyword. undefined is a type with exactly one value: undefined.

Assigning a new value to it does not change the value of the type undefined.

**8 Ways to get Undefined:**

* A declared variable without assigning any value to it.
* Implicit returns of functions due to missing return statements.
* return statements that do not explicitly return anything.
* Lookups of non-existent properties in an object.
* Function parameters that have not passed.
* Anything that has been set to the value of undefined.
* Any expression in the form of void(expression)
* The value of the global variable `undefined`

### **null**

Means **empty or non-existent value**. Used by programmers to indicate “no value”.

**Primitive value.** Not an object. You can assign null to any variable.

Sometimes people wrongly assume that it is an object, because typeof null returns "object".

`null == undefined` ref: [history of typeof null](http://www.2ality.com/2013/10/typeof-null.html)

## `undefined` vs `not defined`

If you try to use a variable that doesn't exist and has not been declared, then JavaScript will throw an error `var name is not defined` and the script will stop executing thereafter. But If you use `typeof undeclared_variable`then it will return `undefined`.

### declaration vs definition

`var x` is a **declaration** because you are not defining what value it holds yet, but you are declaring its existence and the need for memory allocation.

`var x = 1` is both **declaration and definition** (also we can say we are doing initialisation).

Every variable declaration and function declaration brings to the top of its current scope in which it's declared then assignment happen in order this term is called **`hoisting`**.

**A variable can be declared but not defined. When we try to access it, It will result `undefined`.**

```
var x; // Declaration
typeof x === 'undefined'; // Will return true
```

A variable can be neither declared nor defined. When we try to reference such variable then the result will be `not defined`.

```
console.log(y);  // Output: ReferenceError: y is not defined
```

### == vs ===

\== will not check types and === will check whether both sides are of same type.

**== converts to its convenient type to have both in same type** and then do the comparison.

**=== compares the types and values**. Hence, if both sides are not same type, answer is always false.

**Rule for implicit coercion:**&#x20;

* If both operands are same type use ===
* undefined == null
* If one operands is string another is number, convert string to number
* If one is boolean and another is non-boolean, convert boolean to number and then perform comparison
* While comparing a string or number to an object, try to convert the object to a primitive type and then try to compare

Be careful while comparing objects, identifiers must reference the same objects or same array.

```javascript
var a = {a: 1};
var b = {a: 1};
a == b //false
a === b //false

var c = a;
a == c//true
a === c //true
```

Special note: NaN, null and undefined will never === another type. NaN does not even === itself.

**Homework:** [Read confusing special cases of NaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN)

## Object Equality. Comparing objects

**2 approaches** for testing equalit&#x79;**:**

1. **Primitives** (strings, numbers): are compared **by their value**
2. **Objects** (arrays, dates, and user defined objects) are compared **by their reference**. Ie. referring to the same location in memory.

Equality check for objects will check whether two objects have same value for same property. To check that:

1. you can get the keys for both the objects. If the number of properties doesn't match, these two objects are not equal.
2. check each property whether they have the same value. If all the properties have same value, they are equal.

```javascript
function isEqual(a, b) {
    var aProps = Object.getOwnPropertyNames(a),
        bProps = Object.getOwnPropertyNames(b);

    if (aProps.length != bProps.length) {
        return false;
    }

    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i];
        
        if (a[propName] !== b[propName]) {
            return false;
        }
    }
    return true;
}
```

**Limitation:**

* If one of the property values is itself an object
* If one of the property values is NaN (the only value in JavaScript that is not equal to itself?)
* If one object has a property with value undefined, while another object doesn't have the property (which thus evaluates as undefined). Btw, you can solve this problem by using hasOwnProperty

ref: [object equality in JS](http://designpepper.com/blog/drips/object-equality-in-javascript.html), [Underscore.js isEqual function](http://underscorejs.org/docs/underscore.html#section-90)

### typeof **vs** instanceof

`typeof` is an operator that returns a string with the type of whatever you pass.

The `typeof` operator checks if a value belongs to one of the seven basic types: `number`, `string`, `boolean`, `object`, `function`, `undefined` or `Symbol`.

`typeof(null)` will return `object`.

`instanceof` is much more intelligent: it works on the level of prototypes. In particular, it tests to see if the right operand appears anywhere in the prototype chain of the left. `instanceof` doesn’t work with primitive types. It `instanceof`operator checks the current object and returns true if the object is of the specified type, for example:

```
var dog = new Animal();
dog instanceof Animal; // Output : true
```

Here `dog instanceof Animal` is true since `dog` inherits from `Animal.prototype`

```
var name = new String("xyz");
name instanceof String; // Output : true
```

## Function vs Method vs Constructor

### Functions

The simplest usage:

```javascript
function helloWorld(name) {
  return "hello world, " + name;
}

helloWorld("JS Geeks"); // "hello world JS Geeks"
```

### Methods

**Object properties** that are functions.

```javascript
var obj = {
  helloWorld : function() {
    return "hello world, " + this.name;
  },
  name: 'John Carter'
}
obj.helloWorld(); // // "hello world John Carter"
```

Notice how `helloWorld` refer to `this` properties of obj. Here it's clear or you might have already understood that `this`gets bound to `obj`. But the interesting point that we can copy a reference to the same function `helloWorld` in another object and get a difference answer. Let see:

```javascript
var obj2 = {
  helloWorld : obj.helloWorld,
  name: 'John Doe'
}
obj2.helloWorld(); // "hello world John Doe"
```

You might be wonder what exactly happens in a method call here. Here we call the expression itself determine the binding of this `this`, The expression `obj2.helloWorld()` looks up the `helloWorld` property of obj and calls it with receiver object `obj2`.

### Constructors

**Create and initialize** a brand new object and passes it as the value of `this`

Implicitly returns the new object as its result.

```javascript
function Employee(name, age) {
  this.name = name;
  this.age = age;
}

var emp1 = new Employee('John Doe', 28);
emp1.name; // "John Doe"
emp1.age; // 28
```

## Ways of creating objects

### **1. Function based**

Useful if we want to create several similar objects. In the code sample below, we wrote the function `Employee` and used it as a constructor by calling it with the `new` operator.

```
  function Employee(fName, lName, age, salary){
  	this.firstName = fName;
  	this.lastName = lName;
  	this.age = age;
  	this.salary = salary;
  }

  // Creating multiple object which have similar property but diff value assigned to object property.
  var employee1 = new Employee('John', 'Moto', 24, '5000$');
  var employee1 = new Employee('Ryan', 'Jor', 26, '3000$');
  var employee1 = new Employee('Andre', 'Salt', 26, '4000$');
```

### **2. Object Literal**

The best way to create an object and this is used frequently. Below is code sample for create employee object which contains property as well as method.

```
var employee = {
	name : 'Nishant',
	salary : 245678,
	getName : function(){
		return this.name;
	}
}
```

The code sample below is Nested Object Literal, Here address is an object inside employee object.

```
var employee = {
	name : 'Nishant',
	salary : 245678,
	address : {
		addressLine1 : 'BITS Pilani',
		addressLine2 : 'Vidya Vihar'.
		phoneNumber: {
		  workPhone: 7098889765,
		  homePhone: 1234567898
		}
	}
}
```

### **3. new keyword**

Example:

```
var employee = new Object(); // Created employee object using new keywords and Object()
employee.name = 'Nishant';
employee.getName = function(){
	return this.name;
}
```

### **4. Object.create()**

`Object.create(obj)` will create a new object and set the `obj` as its prototype.

Modern way to create objects that inherit properties from other objects. `Object.create` function doesn’t run the constructor.

Use `Object.create(null)` when you don’t want your object to inherit the properties of `Object`.

## Function statements vs Function expressions

### Function statements

Defined at **parse-time**

```javascript
// Parse-Time function declaration
bar(); // Call bar function here, It will not give an Error
function bar() {
  console.log("Hi I am inside Foo");
}
```

### Function expressions

Defined at **runtime**

`var`-declared variables and functions are **hoisted (**&#x4A;S interpreter looks ahead to find all the variable declaration and hoists them to the top of the function where it's declared).

```javascript
// Run-Time function declaration
foo(); // Call foo function here, It will give an error
var foo = function() {
  console.log("Hi I am inside Foo");
};
```

## IIFE's

**Immediately Invoked Function Expression**

Function that **runs as soon as it's defined**.

Usually it's **anonymous**, but it also can be named.

Example:

```javascript
(function() {
  console.log("Hi, I'm IIFE!");
})();
// outputs "Hi, I'm IIFE!"
```

## **typeof() vs instanceOf()**

### **typeof()**

operator that returns a string with the type of whatever you pass.

Checks if a value belongs to one of the seven basic types: `number`, `string`, `boolean`, `object`, `function`, `undefined` or `Symbol`.

`typeof(null)` will return `object`.

### instanceof()

Is much more intelligent: it works on the level of prototypes.

It tests to see if the right operand appears anywhere in the prototype chain of the left.

It doesn’t work with primitive types. It `instanceof`operator checks the current object and returns true if the object is of the specified type

## **Functional vs Object Oriented programming**

### **OOP Pros:**

It’s easy to understand the basic concept of objects and easy to interpret the meaning of method calls. OOP tends to use an imperative style rather than a declarative style, which reads like a straight-forward set of instructions for the computer to follow.

### **OOP Cons**

Depends on shared state. Objects and behaviors are typically tacked together on the same entity, which may be accessed at random by any number of functions with non-deterministic order, which may lead to undesirable behavior such as race conditions.

### **FP Pros**

**FP avoids any shared state or side-effects**: eliminates bugs caused by multiple functions competing for the same resources. With features such as the availability of point-free style (aka tacit programming), functions tend to be radically simplified and easily recomposed for more generally reusable code compared to OOP.

**Favors declarative and denotational styles**, which do not spell out step-by-step instructions for operations, but instead concentrate on **what** to do, letting the underlying functions take care of the **how**. This leaves tremendous latitude for refactoring and performance optimization, even allowing you to replace entire algorithms with more efficient ones with very little code change. (e.g., memoize, or use lazy evaluation in place of eager evaluation.)

**Easy to scale across multiple processors**, or across distributed computing clusters without fear of threading resource conflicts, race conditions, etc…

### **FP Cons**

Over exploitation **can potentially reduce readability** because the resulting code is often more abstractly specified, more terse, and less concrete.

More people are familiar with *OO* and imperative programming than functional programming, can be confusing.

**Steeper learning curve** than OOP.

## Closures

**Inner function that has access to the variables in the outer** (enclosing) function’s scope chain, **even after the outer function has returned**.

To use a closure: define a function inside another function and expose it (return it or pass it to another function).

Have access to variables in **3 scopes**:

1. Its **own** scope
2. The **enclosing** function’s scope
3. **Global** variables

Example:

```javascript
var globalVar = "xyz";

(function outerFunc(outerArg) {
    var outerVar = 'a';
    
    (function innerFunc(innerArg) {
    var innerVar = 'b';
    
    console.log(
        "outerArg = " + outerArg + "\n" +
        "innerArg = " + innerArg + "\n" +
        "outerVar = " + outerVar + "\n" +
        "innerVar = " + innerVar + "\n" +
        "globalVar = " + globalVar);
    
    })(456);
})(123);
```

Variables from `innerFunc`, `outerFunc`, and the global namespace are **all** in scope in the `innerFunc`.

Output:

```javascript
outerArg = 123
innerArg = 456
outerVar = a
innerVar = b
globalVar = xyz
```

### Uses

1. To give objects **data privacy:** the enclosed variables are only in scope within the containing (outer) function. You can’t get at the data from an outside scope except through the object’s **privileged methods**.
2. To create **stateful functions** whose return values may be influenced by their internal state, e.g.: `const secret = msg => () => msg;`
3. In **functional programming**: for partial application & currying

## **Currying**

Pattern where a function with more than one parameter is broken into multiple functions that, when called in series, will accumulate all of the required parameters one at a time.

Useful for making code written in a functional style easier to read and compose.

For a function to be curried, it needs to start out as one function, then broken out into a sequence of functions that each accepts one parameter.

```javascript
function curry(fn) {
  if (fn.length === 0) {
    return fn;
  }

  function _curried(depth, args) {
    return function(newArgument) {
      if (depth - 1 === 0) {
        return fn(...args, newArgument);
      }
      return _curried(depth - 1, [...args, newArgument]);
    };
  }

  return _curried(fn.length, []);
}

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

var curriedAdd = curry(add);
var addFive = curriedAdd(5);

var result = [0, 1, 2, 3, 4, 5].map(addFive); // [5, 6, 7, 8, 9, 10]
```

**References**

* <https://hackernoon.com/currying-in-js-d9ddc64f162e>

## **Monolithic vs Microservice architectures**

### **Monolithic architecture**

App is written as one cohesive unit of code whose components are designed to work together, **sharing the same memory space and resources**.

#### **Pros**

1. Most apps typically have a large number of cross-cutting concerns, such as logging, rate limiting, and security features such audit trails and DOS protection. When everything is running through the same app, it’s easy to hook up components to those cross-cutting concerns.
2. **Performance** advantages, since shared-memory access is faster than inter-process communication (IPC).

#### **Cons**

1. **Tightly coupled** and entangled as the application evolves. Difficult to isolate services for purposes such as independent scaling or code maintainability.
2. **Harder to understand**: dependencies, side-effect&#x73;**.**

### **Microservice architecture**&#x20;

App is made up of **lots of smaller, independent applications** capable of running in their own memory space and **scaling independently from each other** across potentially many separate machines.

#### **Microservice pros**

1. **Better organized**. Each microservice has a very specific job, and is not concerned with the jobs of other components. Decoupled services are also **easier to recompose and reconfigure** to serve the purposes of different apps.
2. **Performance** advantages: **independently scalable** microservices.

#### **Microservice cons**

1. As you’re building a new microservice architecture, you’re likely to discover lots of **cross-cutting concerns** that you did not anticipate at design time. A monolithic app could establish shared magic helpers or middleware to handle such cross-cutting concerns without much effort.
2. **Overhead** of separate modules for each cross-cutting concern, or encapsulate cross-cutting concerns in another service layer that all traffic gets routed through. Eventually, even monolthic architectures tend to route traffic through an outer service layer for cross-cutting concerns, but with a monolithic architecture, it’s possible to delay the cost of that work until the project is much more mature.
3. Frequently deployed on their own virtual machines or containers, causing a **proliferation of VM wrangling work**. These tasks are frequently automated with container fleet management tools.
4. **Performance overhead** caused by **IPC** and **network communication**.

## **Two-way data binding vs One-way data flow**

### Two-way data binding

* **UI fields are bound to model data dynamically**
* When a UI field changes, the model data changes with it and vice-versa.
* Example: **Angular**

### One-way data flow

* The **model is the single source of truth**.
* Changes in the UI trigger messages that signal user intent to the model (or “store” in React)
* Only the model has the access to change the app’s state. The effect is that data always flows in a single direction, which makes it easier to understand.
* Example: **React**

## **Event delegation**

Adding event listeners to a parent element instead of adding them to the descendant elements.

The listener will fire whenever the event is triggered on the descendant elements due to event bubbling up the DOM.&#x20;

Attach a single event listener, to a parent element, that will fire for all children matching a selector, whether those children exist now or are added in the future. The underlying mechanism is browser's **event bubbling** .

Benefits:

* **Memory footprint goes down.** Only one single handler is needed on the parent element, rather than having to attach event handlers on each descendant.
* No need to unbind the handler from elements that are removed and to bind the event for new elements.

**References**

* <https://davidwalsh.name/event-delegate>
* <https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation>

## Event bubbling

When an event triggers on a DOM element, it will attempt to handle the event if there is a listener attached, then the event is bubbled up to its parent and the same thing happens. This bubbling occurs up the element's ancestors all the way to the `document`.&#x20;

The mechanism behind **event delegation**.

## Code organization (modeula pattern, classical inheritance)

## call() vs apply()

Both `.call` and `.apply` are used to **invoke functions and the first parameter will be used as the value of `this` within the function**.

`.call` takes in **comma-separated arguments** as the next arguments

`.apply` takes in an **array of arguments** as the next argument.

Way to remember this is C for `call` and comma-separated and A for `apply` and an array of arguments.

## strict mode

**`'use strict';`** enables strict mode to entire scripts or individual functions.&#x20;

**Strict mode** is a way to opt into a restricted variant of JavaScript.

### Advantages:

* Impossible to accidentally create global variables.
* Assignments which would otherwise silently fail to throw an exception.
* Attempts to delete undeletable properties throw (where before the attempt would simply have no effect).
* Requires that function parameter names be unique.
* `this` is undefined in the global context.
* Catches some common coding bloopers, throwing exceptions.
* Disables features that are confusing or poorly thought out.

### Disadvantages:

* Many missing features that some developers might be used to.
* No more access to `function.caller` and `function.arguments`.
* Concatenation of scripts written in different strict modes might cause issues.

Overall, I think the benefits outweigh the disadvantages.

## Cloning an object

```javascript
var obj = {a: 1 ,b: 2}
var objclone = Object.assign({},obj);
```

Now the value of objclone is `{a: 1 ,b: 2}` but points to a different object than `obj`.

Note the potential pitfall, though: `Object.clone()` will just do a shallow copy, *not* a deep copy. This means that nested objects aren’t copied. They still refer to the same nested objects as the original:

```javascript
let obj = {
    a: 1,
    b: 2,
    c: {
        age: 30
    }
};

var objclone = Object.assign({},obj);
console.log('objclone: ', objclone);

obj.c.age = 45;
console.log('After Change - obj: ', obj);           // 45 - This also changes
console.log('After Change - objclone: ', objclone); // 45
```

## Iterating over object properties and array items

### Objects:

* **for-in loops** - `for (var property in obj) { console.log(property); }`. However, this will also iterate through its inherited properties, and you will add an `obj.hasOwnProperty(property)` check before using it.
* **Object.keys()** - `Object.keys(obj).forEach(function (property) { ... })`. `Object.keys()` is a static method that will lists all enumerable properties of the object that you pass it.
* **Object.getOwnPropertyNames()** - `Object.getOwnPropertyNames(obj).forEach(function (property) { ... })`. `Object.getOwnPropertyNames()` is a static method that will lists all enumerable and non-enumerable properties of the object that you pass it.

### Arrays:

* **`for loops`** - `for (var i = 0; i < arr.length; i++)`. The common pitfall here is that `var` is in the function scope and not the block scope and most of the time you would want block scoped iterator variable. ES2015 introduces `let`which has block scope and it is recommended to use that instead. So this becomes: `for (let i = 0; i < arr.length; i++)`.
* **forEach** - `arr.forEach(function (el, index) { ... })`. This construct can be more convenient at times because you do not have to use the `index` if all you need is the array elements. There are also the `every` and `some` methods which will allow you to terminate the iteration early.
* **`for-of loops`** - `for (let elem of arr) { ... }`. ES6 introduces a new loop, the `for-of` loop, that allows you to loop over objects that conform to the [iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol) such as `String`, `Array`, `Map`, `Set`, etc. It combines the advantages of the `for` loop and the `forEach()` method. The advantage of the `for` loop is that you can break from it, and the advantage of `forEach()` is that it is more concise than the `for` loop because you don't need a counter variable. With the `for-of` loop, you get both the ability to break from a loop and a more concise syntax.

Most of the time, I would prefer the `.forEach` method, but it really depends on what you are trying to do. Before ES6, we used `for` loops when we needed to prematurely terminate the loop using `break`. But now with ES6, we can do that with `for-of` loops. I would use `for` loops when I need even more flexibility, such as incrementing the iterator more than once per loop.

When using the `for-of` loop, if you need to **access both the index and value of each array element**, you can do so with the ES6 Array **`entries()`** method and destructuring:

```javascript
const arr = ['a', 'b', 'c'];

for (let [index, elem] of arr.entries()) { 
  console.log(index, ': ', elem);
}
```

## Add an element at the beginning / end of an array

```javascript
var myArray = ['a', 'b', 'c', 'd'];
myArray.push('end');
myArray.unshift('start');
console.log(myArray); // ["start", "a", "b", "c", "d", "end"]
```

With ES6, one can use the **spread operator**:

```javascript
myArray = ['start', ...myArray];
myArray = [...myArray, 'end'];
```

Or, in short:

```javascript
myArray = ['start', ...myArray, 'end'];
```
