/javascript-cheatsheet

Cheatsheet for the JavaScript knowledge you will frequently encounter in modern projects.

MIT LicenseMIT

JavaScript Cheatsheet

JavaScript is a dynamic interpreted language that powers the web. It is widely used in browsers and increasingly on servers. This document is a cheatsheet for JavaScript you will frequently encounter in modern projects and most contemporary sample code.

Click ⭐if you like the project. Pull Request are highly appreciated. Follow me @itsSunilPradhan on Twitter or Hello Sunil for technical updates and in depth tech articles.

Table of Contents

Motivation

This guide is not intended to teach you JavaScript from the ground up, but to help developers with basic knowledge who may struggle to get familiar with modern codebases (or let's say to learn React for instance) because of the JavaScript concepts used.

Note: Most of the concepts introduced here are coming from a JavaScript language update ES6 or later.

JavaScript Basics

JavaScript was created at Netscape in the early days of the web and initially it had another name: “LiveScript”, but Java was very popular at that time, so it was decided that positioning a new language as a younger brother of Java would help to increase its popularity.

Later Netscape submitted the language for standardization to ECMA(European Computer Manufacturer’s Association) and because of trademark issues, the standardized version of the language was stuck with the awkward name “ECMAScript.” In practice, everyone just calls the language JavaScript.

Today, JavaScript can execute not only in the browser, but also on the server, or actually on any device that has a special program called the JavaScript Engine.

The browser has an embedded engine sometimes called a “JavaScript virtual machine”.

Different engines have different code names. For example:

For most of the 2010s, version 5 of the ECMAScript standard has been supported by all web browsers. ES6 was released in 2015 and added major new features—including class and module syntax—that changed JavaScript from a scripting language into a serious, general-purpose language suitable for large-scale software engineering.

Since ES6, the ECMAScript specification has moved to a yearly release cadence, and versions of the language—ES2016, ES2017, ES2018, ES2019, ES2020 and ES2021—are now identified by year of release.

ECMAScript(JavaScript) standardized by the ECMA International standards organization in the ECMA-262 and ECMA-402 specifications.

Each proposal for an ECMAScript feature goes through the following maturity stages:

  1. Stage 0: Strawman;
  2. Stage 1: Proposal;
  3. Stage 2: Draft;
  4. Stage 3: Candidate;
  5. Stage 4: Finished.

Version History of JavaScript

Edition Date
ES2015 (ES6) June 2015
ES2016 June 2016
ES2017 June 2017
ES2018 June 2018
ES2019 June 2019
ES2020 June 2020

Developer console

In the browser you aren't going to see errors by default. So, if something goes wrong in the script, you won’t see what’s broken and can’t fix it.

To see errors and get a lot of other useful information about scripts, “developer tools” have been embedded in browsers.

Most developers lean towards Chrome or Firefox for development because those browsers have the best developer tools.

Chrome DevTools:

Chrome DevTools

By pressing F12 Chrome DevTools window open up.

Firefox Developer Tools:

Firefox Developer Tools

By pressing F12 Firefox Developer Tools window open up.

💡 TIP: Multi-line input

Usually, when we put a line of code into the Chrome DevTools/Firefox Developer Tools console, and then press Enter ⏎ , it executes.

To insert multiple lines, press Shift + Enter ⏎. This way one can enter long fragments of JavaScript code easily.

async & defer attribute:

async

<script scr="./script.js" async> </script>

The async attribute is a boolean attribute. When present, it specifies that the script will be executed asynchronously as soon as it is available.

defer

<script src="demo_defer.js" defer></script>

The defer attribute is a boolean attribute. When present, it specifies that the script is executed when the page has finished parsing.

In other words, downloads the script while the page content is downloading, and executes after the HTML is parsed.

Further Reading

Remember - Everything in JavaScript is an object and Its code runs top to bottom and left to right.

JavaScript comments

Single line comments start with //. For multi-line commands, you use /* ... */.

// This is a single line comment

/*
 And this is
 a multi-line
 comment
 */

JavaScript Literals & Identifiers

Literals: JavaScript literals are fixed values.

Example:

12; // The number twelve
1.2; // The number one point two
('hello world'); // A string of text

Identifiers: All JavaScript variables, constants, properties, functions and classes must be identified with unique names. These unique names are called identifiers and these are case sensitive.

A JavaScript identifier must begin with a letter, an underscore (_), or a dollar sign ($).

Example:

i my_variable_name
v13
_dummy
$str

JavaScript expression

A fragment of code that produces a value is called an expression.

5 * 10; //5 * 10 evaluates to 50

x * 10; //expressions can also contain variable values

JavaScript statement

A JavaScript program is a list of instructions to be executed by a computer and these programming instructions are called statements.

var x, y, z; //statement 1
x = 5; //statement 2
y = 6; //statement 3
z = x + y; //statement 4

If an expression corresponds to a sentence fragment, a JavaScript statement corresponds to a full sentence in a human language.

Roughly, an expression is something that computes a value but doesn’t do anything: it doesn’t alter the program state in any way. Statements, on the other hand, don’t have a value, but they do alter the state.

Terminate statements in JavaScript

doStuff(); // Semicolons (;) to terminate lines

JavaScript reserved words

These reserved keywords must not be used as the names of constants, variables, functions, or classes.

Column A Column B Column C
as const export
get null target
void async continue
extends if of
this while await
debugger false import
return throw with
break default finally
in set true
yield case delete
for instanceof static
try catch do
from let super
typeof class else
function new switch
var - -

JavaScript also restricts the use of certain keywords that are not currently used by the language but that might be used in future versions:

Column A Column B Column C
enum implements interface
package private protected
public - -

💡 Note: For historical reasons, arguments and eval are not allowed as identifiers in certain circumstances and are best avoided entirely.

JavaScript & Unicode

You can use Unicode character set in strings, comments and identifiers (but not emojis).

This means that programmers can use mathematical symbols and words from non-English languages as constants and variables.

Example:

const π = 3.14;
const  = true;

↥ back to top

Variables

In JavaScript, a variable is like a temporary location where you store your data for future retrieval.

There are 3 ways to create variables in JavaScript:

var, let, const

Variables created with var are in scope of the function (or global if declared in the global scope); let variables are block scoped; and const variables are like let plus their values cannot be re-assigned.

I recommend always declaring your variables with const by default, but with let if it is a variable that you need to reassign later.

js-variables-let-const-var

💡 TIP: The Temporal Dead Zone(TDZ) is never named explicitly in the ECMAScript specification, but the term is often used to describe why let and const bindings are not accessible before their declaration.

Example

const person = "Sunil";
person = "Anil" // Will raise an error, person can't be reassigned
let person = "Sunil";
person = "Anil";
console.log(person) // "Anil", reassignment is allowed with let

Variable declaration:

// This is how you define a variable
// x will be undefined
var x;

// Declare a constant (the convention is to use CAPS for constants)
const PI = 3.14;

// Declare another two variables, using var and let
var firstName = 'Sunil';
let lastName = 'Pradhan';

Re-declaring a JavaScript variable:

If you re-declare a JavaScript variable, it will not lose its value.

var x = 4;
var x;
console.log(x);

//output - 4

💡 TIP: JavaScript statements are executed, one by one, in the same order as they are written.


↥ back to top

Data types

Type of data:

In JavaScript two types of data type available:

  • Primitive
  • Reference or derived type

What is the difference between both of them?

Primitive data types are base data types whereas reference data types are derived.

💡 TIP: Memory allocation in primitive data types happens in “Stack” whereas memory allocation in Reference data types happens in “Heap” (Dynamic memory).



The latest ECMAScript standard defines nine data types:

Seven primitive data types:

  • Undefined
  • Boolean
  • Number
  • String
  • BigInt
  • Symbol
  • Null

Two derived data types (non-primitive):

  • Object
  • Function
Further Reading

↥ back to top

Undefined:

The meaning of undefined is “value is not assigned”, that means if a variable is declared, but not assigned, then its value is undefined:

Example:

var x;
console.log(typeof x);  //output - undefined

Without initialization we try to access it here, so that it throws us undefined.

Technically, it is possible to assign undefined to any variable:

 var x = 123;
 x = undefined;
 console.log(typeof x);  //output - undefined

But it is not recommended. Normally, we use null to assign an “empty” or “unknown” value to a variable, and we use undefined for checks like seeing if a variable has been assigned or not.

8 Ways to get undefined:

1. A declared variable without assigning any value to it.

Example:

var x;
console.log(typeof x);  //output - undefined

2. Implicit returns of functions due to missing return statements.

Example:

function demo() {}
console.log(demo());  //output - undefined

3. return statements that do not explicitly return anything.

function demo() {
return;
}
console.log(demo()); //output - undefined

Boolean:

Booleans can only have two values: true or false.

Example:

var x = true;
console.log(typeof x);  //output - boolean

Number:

JavaScript has only one type of number and it can be written with or without decimals.

Example:

var age = 18;
console.log(typeof age);   //output - number

String:

A string is a series of characters like "Sunil Pradhan".

Example:

var name = 'Sunil';
console.log(typeof name);   //output - string

In JavaScript, there are three types of quotes for strings.

  • Double quotes
  • Single quotes
  • Backticks
 let str = "Hello"; //double quotes
 let str2 = 'Single quotes are ok too';   //single quotes
 let phrase = 'can embed another ${str}'  //backticks

Double and single quotes are simple quotes. There’s practically no difference between them in JavaScript.

On the other hand, backticks are extended functionality quotes. They allow us to embed variables and expressions into a string by wrapping them in ${…}, for example:

  let name = "Sunil"

  //embed a variable 
  console.log(`Hello, ${name}!`);   //Hello, Sunil!
  //embed an expression
  console.log(`The result is ${1 + 2}`);   //The result is 3

BigInt:

In JavaScript, the number type cannot represent integer values larger than 253 (or less than -253 for negatives), that’s a technical limitation caused by their internal representation. That’s about 16 decimal digits, so for most purposes the limitation isn’t a problem, but sometimes we need really big numbers, e.g. for cryptography or microsecond-precision timestamps.

BigInt type is recently added to the JavaScript language to represent integers of arbitrary length.

A BigInt is created by appending n to the end of an integer literal:

Example:

const x = 123n;  // the 'n' at the end means it's a BigInt

console.log(typeof x);   //output - BigInt

Symbol:

Symbol is used to generate primitives which are unique in nature.

var x = Symbol();
console.log(typeof x);   //output - Symbol

Null:

It’s just a special value which represents “nothing”, “empty” or “value unknown”.

Example:

var x = null;
console.log(typeof x);  //output - object

Here variable is empty so that it is at the beginning behave as a placeholder which you will use to put something inside of it.

The value does not go to undefined so that you have to put initially null which later you can change it to a value.

💡 TIP: Difference between undefined and null in JavaScript

undefined means the value has not been set, whereas null means the value has been set to empty.

var a = null; //null example
var a; //undefined example

↥ back to top

Type Conversions OR Typecasting OR Coercion

Typecasting or coercion in simple terms means to change the data type of a value to another data type like for example, integer to a string or a string to a boolean etc.

There are two types of type casting, implicit and explicit.

Implicit type casting is when there is automatic conversion of data type, whereas when a developer expresses the intention to convert between types by writing the appropriate code, it’s called explicit type casting.

JavaScript supports three type of conversion

  • to string
  • to number
  • to boolean

String Conversion

You can use String() function to convert a value to a string:

Example:

var value = true;
alert(typeof value); //boolean

value = String(value); //now value is a string 'true'
alert(typeof value); //string

Numeric Conversion

You can use Number() function to explicitly convert a value to a number:

Example:

var str = '123';
alert(typeof str); //string

var num = Number(str); //becomes a number 123
alert(typeof num); //number

Rules:

js-numeric-conversion-rules

Boolean Conversion

It happens in logical operations but can also be performed explicitly with a call to Boolean() function.

Rules:

js-boolean-conversion-rules


↥ back to top

JavaScript Operators

Operator Precedence:

Operator precedence describes the order in which operations are performed in an arithmetic expression.

The operator with the lowest number is said to have the highest precedence.

When an expression contains two or more operators that have the same precedence, they are evaluated according to their associativity (Associativity determines whether the operators are evaluated from left to right or right to left).

💡 TIP: Find operator precedence table at MDN web docs.


↥ back to top

Comparison Operators:

js-comparison-operators


↥ back to top

Bitwise Operators:

Bitwise operators compare bit to bit.

js-bitwise-operators


↥ back to top

Assignment Operators:

Basic assignment:

var a = 10;
console.log(a);

//output 10

Addition assignment:

var a = 10;
a += 2; // a = a+2
console.log(a);

//output 12

Subtraction assignment:

var a = 10;
a -= 2; // a = a-2
console.log(a);

//output 8

Multiplication assignment:

var a = 10;
a *= 2; // a = a*2
console.log(a);

//output 20

Division assignment:

var a = 10;
a /= 2; // a = a/2
console.log(a);

//output 5

Modulus assignment:

var a = 10;
a %= 2; // a = a%2
console.log(a);

//output 0

↥ back to top

Exponentiation Operator:

The exponentiation operator ** is a recent addition to the JavaScript language.

The result of a ** b is a multiplied by itself b times.

Example:

alert(2 ** 2);

//output 4 (2*2)

Example:

alert(2 ** 3);

//output 8 (2*2*2)

↥ back to top

Increment and decrement Operators:

Increment Example:

var a = 20;
a++;
var b = 10;
var c = a + b;
console.log(c);

//output 31

Decrement Example:

var a = 20;
a--;
var b = 10;
var c = a + b;
console.log(c);

//output 29

Increment/decrement can only be applied to variables. Trying to use it on a value like 5++ will give an error.

The operators ++ and -- can be placed either before or after a variable.

When the operator goes after the variable, it is in “postfix form”: counter++

The “prefix form” is when the operator goes before the variable: ++counter

Both of these statements do the same thing: increase counter by 1.

Is there any difference?

Yes, but you can only see it if you use the returned value of ++/--.

Let’s clarify. As we know, all operators return a value. Increment/decrement is no exception. The prefix form returns the new value while the postfix form returns the old value (prior to increment/decrement).

Example(prefix):

var counter = 1;
var a = ++counter;
console.log(a);

//output 2

Example(postfix):

var counter = 1;
var a = counter++;
console.log(a);

//output 1

↥ back to top

typeof operator:

The typeof operator is used to get the data type of its operand. The operand can be either a literal or a data structure such as a variable, a function, or an object.

var a = 10;
console.log(typeof a);

//output - number

↥ back to top

Branches and Loops

Branching Out:

if statement

It is used to execute an instruction or block of instructions only if a condition is fulfilled i.e True.

Syntax:

if (condition) {
  // Statements to execute if condition is true
}

Example:

var x = 10;
if (x == 10) {
  console.log(x);
}
//if the value is true then display 10 on the screen

//output - 10

↥ back to top

if...else statement

if...else statement is used when a different sequence of instructions is to be executed depending on the logical value(true, false) of the conditions evaluated.

Syntax:

if (condition) {
  // Executes this block if condition is true
} else {
  // Executes this block if condition is false
}

Example:

var x = 10;
if (x == 11) {
  console.log('Hello World!');
} else {
  console.log('Sorry!');
}
//if statement false then display else statement

//output - sorry!

↥ back to top

Nested if statement

Embedding if statement inside another if statement is called nested if statement. Here, else statement allows you to print different statements depending upon the expression result (true, false).

Syntax:

if (condition1) {
  // Executes when condition1 is true
  if (condition2) {
    // Executes when condition2 is true
  }
}

Example:

var firstName = 'Sunil';
var lastName = 'Pradhan';

if (firstName == 'Sunil') {
  if ((lastName = 'Pradhan')) {
    console.log('Hello! Sunil Pradhan');
  } else {
    console.log('Hello! you are someone else');
  }
}

//output - Hello! Sunil Pradhan

↥ back to top

if-else-if ladder or else...if statement

Use else...if to specify a new condition to test, if the first condition is false.

Syntax:

if (condition_1) {
  //statement_1_block;
} else if (condition_2) {
  //statement_2_block;
} else if (condition_n) {
  //statement_n_block;
}
.
.
.
else statment;

First check if statement condition 1, if it's not true then go to condition 2 and check. Still it’s not true then go to condition 3 and so on, until you are not getting any true value, otherwise show the else statement.

Example:

var result = 38;
if (result <= 30) {
  console.log('You are failed');
} else if (result <= 40) {
  console.log('You are passed');
} else if (result <= 60) {
  console.log('You are good');
} else {
  console.log('You are very good');
}

//output - You are passed

↥ back to top

Switch statement

The switch statement chooses between multiple statements to execute based on possible values of a single expression. Each of these values in a switch statement is called a case.

Syntax:

switch (expression)
{
    case value1:
        statement1;
        break;
    case value2:
        statement2;
        break;
    .
    .
    case valueN:
        statementN;
        break;
    default:
        statementDefault;
}

💡 TIP: All the cases will be evaluated if you do not use a break statement.

Example: (Without default)

var day = 1;
switch (day) {
  case 1:
    console.log('Sun');
    break;

  case 2:
    console.log('Mon');
    break;
}

//output - Sun

Example: (With default)

var day = 5;
swtich(day) {
  case 1:
  console.log('Sun');
  break;

  case 2:
  console.log('Mon');
  break;

  default:
  console.log('It is wrong!');
}

//output - It is wrong!

Sometimes it is also possible or necessary to execute the same statement for multiple expressions.

Syntax:

switch (expression)
{
    case value1:
        statement1;
        break;
    case value2:
    case value3:
        statement3;
        break;
    .
    .
    case valueN:
        statementN;
        break;
    default:
        statementDefault;
}

Example: In a week, if you have two days off then in that case you can use switch statements where you need to execute the same statement multiple times.

Example: (With multiple options)

var day = 4;
switch (day) {
  case 1:
    console.log('Mon - Office day');
    break;

  case 2:
    console.log('Tue - Office day');
    break;

  case 3:
  case 4:
    console.log('Wed/Thu - Off day');
    break;

  default:
    console.log('You do not have off');
}

//output - Wed/Thu - Off day

↥ back to top

Conditional (Ternary) operator

Example: (By if statement)

function findGreater(a, b) {
  if (a > b) {
    return 'a is greater';
  } else {
    return 'b is greater';
  }
}

console.log(findGreater(3, 1));

//output - a is greater

Example: (By ternary operator)

function findGreater(a, b) {
  return a > b ? 'a is greater' : 'b is greater';
}
console.log(findGreater(3, 1));

//output - a is greater

↥ back to top

Multiple conditional (Ternary) operators

Example: (By if statement)

function findGreaterOrEqual(a, b) {
  if (a === b) {
    return 'a and b are equal';
  } else if (a > b) {
    return 'a is greater';
  } else {
    return 'b is greater';
  }
}
console.log(findGreaterOrEqual(1, 1));

//output - a and b are equal

Example: (By ternary operator)

function findGreaterOrEqual(a, b) {
  return a === b
    ? 'a and b are equal'
    : a > b
    ? 'a is greater'
    : 'b is greater';
}
console.log(findGreaterOrEqual(1, 1));

//output - a and b are equal

💡 TIP: A ternary operator returns the first value if the expression is true, or else returns the second value.

expression ? ifTrue : ifFalse;

↥ back to top

Loop De Loop:

JavaScript supports the following kinds loops:

  • for - loops through a block of code a number of times
  • while - loops through a block of code while a specified condition is true
  • do...while - loops through a block of code while a specified condition is true
  • for...in - loops through the properties of an object
  • for...of - loops through the values of an iterable object

for loop

The for loop is usually used where the loop will be repeated a fixed number of times.

Type 1:

Syntax:

for (initialization condition; testing condition; increment/decrement)
{
    statement(s);
}

First for loop initialize a variable then enter into a test condition. If the condition is true then it will execute the block of statement. After this step, it will reach at the end of the block } but before it goes to the second time looping, it increases one value with the help of an increment operator.

When the loop runs for a second time, it does not even look at the initialized variable because its job has been over.

When the test condition is false then it stops executing the statement.

Example:

var i = 5;
for (i = 0; i <= 5; i++) {
  console.log(i);
}

//output - 0, 1, 2, 3, 4, 5

Type 2:

Example:

var i = 0;
for (; i < 5; i++) {
  console.log(i);
}

//output - 0, 1, 2, 3, 4

Here you define a variable first but in the for loop you are still keeping ; at the initialization stage.

Type 3:

Example:

var i = 0;
for (; i < 5; ) {
  i++;
  console.log(i);
}

//output - 1, 2, 3, 4, 5

Type 4:

Example:

var i = 0;
for (; ; i++) {
  if (i == 3) {
    break;
  }
  console.log(i);
}

//ouput - 0, 1, 2

What it tells us. We have initialized a variable then we have our test condition within the if statement. It checks the condition upto equality 3 then it break the statement and exit from the loop.

Nested for loop

In nested for loop, you are using a for loop inside of another for loop.

Syntax:

for (initialization condition; testing condition; increment/decrement) {

            statement(s);

            for (initialization condition; testing condition; increment/decrement) {
              statement(s);
            }
      }

Example:

for (i = 0; i < 2; i++) {
  console.log('Outer loop i: ' + i);

  for (j = 0; j < 2; j++) {
    console.log('inner loop j: ' + j);
  }
}

//output -
// Outer loop i: 0
// inner loop j: 0
// inner loop j: 1
// Outer loop i: 1
// inner loop j: 0
// inner loop j: 1

↥ back to top

while loop

The while loop keeps repeating an action until an associated condition returns false. The while loop can be thought of as a repeating if statement.

Type 1:

Syntax:

while (test condition) {

    statement(s);
    increment/decrement;
}

We put one test condition at the beginning of the program. Then it will go to the body of the loop, once it finishes its work then it will increment or decrement the value. Finally it will reach the end of the loop where it can start again from starting until the condition is false.

Example:

js-while-loop-type-one

Type 2:

In other cases you can use a while loop when the condition is true forever but you do not know when the loop is going to close.

Example:

js-while-loop-type-two

Nested while loop

In nested while loop, you are using a while loop inside of another while loop.

Example:

js-while-loop-nested


↥ back to top

do...while loop

The do...while loop is similar to while loop, but the condition is checked after the loop body is executed. This ensures that the loop body is run at least once.

Type 1:

Syntax:

do
{
    statement(s)
}
while (condition);

Example:

js-do-while-loop

💡 TIP: In while statement we check condition first but in do..while statement we check condition last.

Type 2:

Example:

js-do-while-loop-type-two

Nested do...while loop

In nested do...while loop, you are using a do...while loop inside of another do...while loop.

Example:

js-do-while-loop-nested


↥ back to top

break and continue keyword in loop

break - stop the loop:

Example:

for (i = 1; i <= 5; i++) {
  if (i == 3) {
    break; //stop loop
  }
  console.log(i);
}

//output - 1, 2

continue - skip the loop:

Example:

for (i = 1; i <= 5; i++) {
  if (i == 3) {
    continue; //skip 3
  }
  console.log(i);
}

//output - 1, 2, 3, 4, 5

↥ back to top

for...in Loop

The for...in loop is used to loop through an object’s properties and methods.

When you want to visit all object properties like its keys then you need to use for..in loop.

Syntax:

for (var variable_name in object_name) {
  //code block
}

Example:

function Mobile(model_no) {
  this.model = model_no;
  this.color = 'white';
  this.ram = '4GB';
}

var samsung = new Mobile('Galaxy');

for (var specs in samsung) {
  console.log(samsung[specs]);
}

//output - Galaxy, white, 4GB

↥ back to top

for...of Loop

The for..of statement creates a loop iterating over iterable objects.

Syntax:

for (var variable_name of array) {
}

Example:

var stu = ['Sunil', 'Ram', 56, 66];

for (var value of stu) {
  console.log(value);
}

//output - Sunil
//output - Ram
//output - 56
//output - 66

Difference between ( for… in ) and ( for… of ) statements in JavaScript:

Both for..in and for..of are looping constructs which are used to iterate over data structures. The only difference is over what they iterate:

for..in iterates over all enumerable property keys of an object for..of iterates over the values of an iterable object. Examples of iterable objects are arrays, strings, and NodeLists.

Example:

let arr = ['el1', 'el2', 'el3'];

arr.addedProp = 'arrProp';

// elKey are the property keys
for (let elKey in arr) {
  console.log(elKey);
}

// elValue are the property values
for (let elValue of arr) {
  console.log(elValue);
}

//output
//0
//1
//2
//addedProp
//el1
//el2
//el3
Reference

https://stackoverflow.com/questions/29285897/what-is-the-difference-between-for-in-and-for-of-statements-in-jav#:~:text=Difference%20for..in%20and%20for,values%20of%20an%20iterable%20object.


↥ back to top

JavaScript Function

Functions are subprograms which are used to compute a value or perform a task.

Type of function:

  • Built-in functions
  • User-defined functions

Creating and calling a function

Syntax:

function function_name() {
  //code block
}
function_name();

Example:

function display() {
  console.log('Hello! Sunil');
}
display();

//output - Hello! Sunil

↥ back to top

Function with parameters

Syntax:

function function_name(parameter1, parameter2) {
  //code block
}

💡 Note:

  • JavaScript function definitions do not specify data types for parameters.
  • JavaScript functions do not perform type checking on the passed arguments
  • JavaScript functions do not check the number of arguments received.

Call function with parameter

Syntax:

function function_name(parameter1, parameter2) {
  //code block
}

function_name(argument1, argument2);

Example:

function display(name) {
  console.log(name);
}
display('Sunil');

//output - Sunil

In JavaScript function parameters behave as variables. So when the display function is called [display(‘Sunil’)], it moves to the top of the function and meets display(name).

display(name) says - I have a parameter(variable) and expecting an argument which I can pass through. Do you have any?

display(‘Sunil’) says - Yes! I have an argument(Sunil). I am giving you.

Now the display(name) is replaced by its argument - display(Sunil).

It goes down to the console and show the output.

Example: (Same number of arguments and parameters)

function display(fname, lname) {
  console.log(fname, lname);
}
display('Sunil', 'Pradhan');

//output - Sunil Pradhan

Example: (different data types in arguments)

function display(fname, age) {
  console.log(fname, age);
}
display('Sunil', 20);

//output - Sunil 20

Example: (argument missing)

function display(fname, age, zip) {
  console.log(fname, age, zip);
}
display('Sunil', 20);

//output - Sunil 20 undefined

If a function is called with missing arguments, the missing values are set to undefined.


↥ back to top

Arguments object in JavaScript

When you call a function and pass the arguments, these arguments are stored in an object.

Example:

function display(fname, lname) {
  console.log(arguments[0]);
  console.log(arguments[1]);
}
display('Sunil', 'Pradhan');

//output
//Sunil
//Pradhan

💡 Note:

The object contains an entry for each argument passed to the function, the first entry’s index starting at 0.

The arguments object is not an Array. It is similar to an Array, but does not have any Array properties except length.

Example: (Change arguments value internally while execution)

function display(fname, lname) {
  arguments[0] = 'Anil';
  console.log(arguments[0]);
  console.log(arguments[1]);
}
display('Sunil', 'Pradhan');

//output
//Anil
//Pradhan

Example: (Length property)

function display(fname, lname) {
  console.log(arguments.length);
}
display('Sunil', 'Pradhan');

//output - 2

Here the length property will show you how many arguments it contains when called by the function.

Example: (Arguments object and for loop)

By using for loop inside arguments object you can retrieve all of the arguments content.

function display(fname, lname) {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i] + '');
  }
}
display('Sunil', 'Pradhan');

//Output
//Sunil
//Pradhan

Example: (Too many arguments)

If you want to pass many arguments which are originally not present in your parameters then also you can display it on your output screen with the help of argument object.

function num(num1, num2) {
  console.log(num1, num2);
  console.log(num1, num2, arguments[2]);
}
num(1, 2, 3);

//Output
// 1 2
// 1 2 3

↥ back to top

Default parameter in JavaScript

When the function called and if it doesn't hold any value inside of it then it will use its default value from parameters to display its output.

Default parameter values always come on last, otherwise it returns undefined. Once default value start then rest of parameters should be default value only.

Syntax:

function function_name(para1, para2 = 'value1', para3 = 'value2') {
  //code block
}

Example:

function num(a, b, c = 70) {
  //c is defined as default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10, 20); //two args

//output - 10, 20, 70

Here we have passed two arguments so that after a and b. It took the default value to show the result of c, i.e 70.

Example: (Three arguments values, default value declared at last)

function num(a, b, c = 70) {
  //c is defined as default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10, 20, 30); //three args

//output - 10, 20, 30

Here we have passed three arguments so that we don’t need to use the default value.

Example: (One arguments value, default value declared at last)

function num(a, b, c = 70) {
  //c is defined as default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10); //one args

//output - 10, undefined, 70

Here we have passed only one argument so that it successfully console out a but when it arrives at b, it doesn’t find any arguments. Hence, it shows undefined.

Due to the default value of c we are getting a result of 70 in the third console statement.

Example: (Three arguments value, default value declared at middle)

function num(a, b = 50, c) {
  //b is defined as default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10, 20, 30); //three args

//output - 10, 20, 30

Here we have passed three arguments and in the middle of parameters we have defined our default value. It still doesn't show undefined because we have passed three arguments.

Hence, it is fetching data from its arguments. But if it misses one argument value then it will again show undefined.

function num(a, b = 50, c) {
  //b is defined as default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10, 20); //30 missing

//output - 10, 20, undefined

If only one argument then it takes default value from b and c would be undefined.

function num(a, b = 50, c) {
  //b is defined as default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10); //one args

//output - 10, 50, undefined

Example: (Multiple default values)

function num(a, b = 50, c = 70) {
  //b and c is defined as default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10); //one args

//output - 10, 50, 70

💡 TIP: JavaScript also allows the use of array and null as default values.


In case of null:

function num(a, b, c = null) {
  //c is defined as null but default value

  console.log(a);
  console.log(b);
  console.log(c);
}
num(10, 20); //two args

//output - 10, 20, null

In case of Array:

function num(a, b = [101]) {
  console.log(a);
  console.log(b);
}
num(5, [10]);
//Passing 10 as an array

//output - 5, 10

Here it doesn't even look at default value because we have passed 10 in our argument.

function num(a, b = [101]) {
  console.log(a);
  console.log(b);
}
num(5);

//output - 5, 101

No value passed so that it is displaying default value.

Example: (Multidimensional array)

function person(age, name = ['Sunil', 'Pradhan']) {
  console.log(age);
  console.log(name);
}
person(20, ['Anil', 'Sahu']);

//Output - 20, Anil Sahu

Example: (with index array number)

function person(age, name = ['Sunil', 'Pradhan']) {
  console.log(age);
  console.log(name[0]);
  console.log(name[1]);
}
person(20, ['Anil', 'Sahu']);

//Output - 20, Anil Sahu

↥ back to top

Return statement in JavaScript function

A return statement in JavaScript function may return any type of data, including arrays and objects.

Syntax:

function function_name(para1, para2,...) {
  //code block
  return (expression);
  //expression can be variable, arrays or objects
}

It says - I am going to return some expression where I am being called for.

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

var x = add(10, 20);
console.log(x);

//output = 30

But what is the benefit of using return statement:

If you want to pass different arguments but with the same parameters then it can be a helpful.

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

console.log(add(10, 20));
console.log(add(1, 2));
console.log(add(2, 2));

//output = 30
//output = 3
//output = 4

↥ back to top

Variable scope in JavaScript function

It has two types:

  • Global Scope
  • Local Scope

Global Scope:

  • A variable that is declared outside a function definition is a global variable, and its value is accessible and modifiable throughout your program.

  • In a web browser, global variables are deleted when you close the browser window (or tab), but remain available to new pages loaded into the same window.

Example:

var x = 'I am global variable';
function show() {
  console.log(x); //inside function
}
show();
console.log(x); //outside function

//output - I am global variable
//output - I am global variable

Local Scope:

  • A variable that is declared inside a function definition is local. It is created and destroyed every time the function is executed, and it cannot be accessed by any code outside the function.
  • Inside a function, if a variable has not been declared with var keyword it is created as a global variable.

Example:

function show() {
  var j = 'I am local variable';
  //local variable
  console.log(j);
}
show();

//output - I am local variable

If try from outside function then:

Example:

function show() {
  var j = 'I am local variable';
  //local variable
  console.log(j);
}
show();
console.log(j);

//output - I am local variable
//output - Error - ReferenceError: j is not defined

But when you try to access other functions local variables from one other function, you would get an error.

Example:

var i = 'I am global';
function show() {
  var j = 'I am local variable';
  //local variable
  console.log(j);
}
show();
console.log(i);

if (true) {
  console.log(j);
}

//output - I am local variable
//output - I am global
//output - ReferenceError: j is not defined

Now try an example where you are not declaring a variable but assign it. In this case it turns into a global variable even if it is a local variable.

Example:

function show() {
  j = 'I am now global variable';
  //it's now global
  console.log(j);
}
show();

console.log(j);

//output - I am now global variable
//output - I am now global variable

💡 TIP: If there is a function inside a function the inner function can access the outer function’s variables but the outer function can not access the inner function’s variables.


💡 TIP: Function arguments (parameters) work as local variables inside functions.

Example:

function show() {
  //local variable

  var j;
  j = 'J a local variable of outer function';
  console.log(j);

  function innerFun() {
    //local variable
    var i;
    i = 'I a local variable of inner function';
    console.log(i);
    console.log(j);
  }
  innerFun();
  console.log(i);
}
show();

//output - J a local variable of outer function
//output - I a local variable of inner function
//output - J a local variable of outer function
//output - ReferenceError: i is not defined

↥ back to top

Block scope in JavaScript function:

Block scope is achieved by JavaScript's two new keyword for variable - let and const.

//block scope
if (true) {
  let i = 10; //local variable
  console.log(i);
}
console.log(i);

//output - 10
//output - ReferenceError: i is not defined

Variable 10 is only available for this if block, outside of this block if you try to access 10 then it would throw an error.


↥ back to top

Closure in JavaScript function

A closure is an inner function that has access to the outer function’s variables.

For every closure we have three scopes:

  • Local scope (Own scope)
  • Outer functions scope
  • Global scope

Outer functions scope

When an inner function variable is able to access an outer function variable then it is called outer function scope.

Example:

var i = 10;
function show() {
  var j = 20;
  console.log(j);
  console.log(i);
  //outer scope
}
show();

//output - 20, 10

💡 TIP: Nested function is closure and closure is also a nested function

Example:

function show() {
  var j = 'j - Local variable of outer function';
  console.log(j);

  function innerFun() {
    var k = 'k - Local variable of inner function';
    console.log(k);
  }
  innerFun();
}
show();

//output - j - Local variable of outer function
//output - k - Local variable of inner function

This is the basic concept of nested function. But where is the closure ??

It is when you are accessing the outer function variable inside of your inner function then its called closure.

function show() {
  var j = 'j - Local variable of outer function';
  console.log(j);

  function innerFun() {
    var k = 'k - Local variable of inner function';
    console.log(k);
    console.log(j);
  }
  innerFun();
}
show();

//output - j - Local variable of outer function
//output - k - Local variable of inner function
//output - j - Local variable of outer function

Here closure is able to access local variables as well as outer function variable and more it can even access global variable in your program too.

Example:

var a = 'Global variable';
console.log(a);
function show() {
  var j = 'j - Local variable of outer function';
  console.log(j);

  function innerFun() {
    var k = 'k - Local variable of inner function';
    console.log(k);
    console.log(j);
    console.log(a);
  }
  innerFun();
}
show();

//output - j - Local variable of outer function
//output - k - Local variable of inner function
//output - j - Local variable of outer function
//output - Global variable

But outer function can not access the inner function variable.

function show() {
  var j = 'j - Local variable of outer function';
  console.log(j);

  function innerFun() {
    var k = 'k - Local variable of inner function';
    console.log(k);
    console.log(j);
  }
  innerFun();
  console.log(k);
}
show();

//output - j - Local variable of outer function
//output - k - Local variable of inner function
//output - j - Local variable of outer function
//output - ReferenceError: k is not defined

↥ back to top

Function expression

When we create a function and assign it to a variable then its called as function expression.

💡 TIP: When you are creating function expression you need to close it by semicolon (;).

Example:

var myfun = function show() {
  console.log('Hello Sunil');
};
myfun();

//output - Hello Sunil

Remember you can not call function expression before function definition else it would throw an error.

Why so?

Function expressions in JavaScript are not hoisted, unlike function declarations.


↥ back to top

Anonymous function

Anonymous functions allow the creation of functions which have no specified name.

In other words, a JavaScript function which does not have any name.

Anonymous function can:

  • Stored in a variable
  • Returned in a function
  • Pass in a function

💡 TIP: When you are creating an anonymous function you need to close it by semicolon (;).

Store anonymous function in a variable:

Example:

var a = function () {
  console.log('Hello Sunil');
};
a();

//output - Hello Sunil

Passing some parameters then;

var a = function (x, y) {
  console.log(x + ' ' + y);
};
a(10, 20);

//output - 10 20

Returning anonymous function

Example:

function test() {
  return function () {
    alert('hi');
  };
}
test()();

//output - hi
Reference

Passing anonymous function as argument:

function disp(myfun) {
  return myfun;
}
console.log(disp('Hello Sunil'));

//output - Hello Sunil

In this example we have passed a string in function as an argument. But now we need to see how to pass an anonymous function as an argument.

function disp(myfun) {
  return myfun();
}
console.log(
  disp(function () {
    return 'Hello Sunil';
  })
);

//Output - Hello Sunil

↥ back to top

Arrow function

An arrow function expression has a shorter syntax compared to function expression. Arrow functions are always anonymous in nature.

In other words, arrow function syntax will be small and it will be anonymous means this function will not have any name.

Syntax:

() => {
  statements;
};

Example:

var myFun = () => {
  console.log('Hello Sunil');
};
myFun();

//output - Hello Sunil

💡 TIP: You can not call arrow function before declaration.

Arrow function with parameters

Example:

var myfun = (a) => {
  console.log(a);
};
myfun(10);

//output - 10

When passing a single parameter it is not mandatory to have ( ), without it also work.

var myfun = (a) => {
  console.log(a);
};
myfun(10);

//output - 10

But if you have multiple parameters then you should use ().

var myfun = (a, b) => {
  console.log(a, b);
};
myfun(10, 20);

//output - 10, 20

If you don't have any parameters then you need to keep ().

var myfun = () => {
  console.log('Sunil');
};
myfun();

//output - Sunil

💡 TIP: If you have a single parameter then it is not mandatory to have () as well as {}. But if you have a block of statement then you need to put {}.

Arrow function with default parameter

Example:

var myfun = (a, b = 20) => {
  console.log(a + ' ' + b);
};

myfun(10);

//output - 10, 20

Arrow function with Rest operator

Example:

var myfun = (a, ...args) => {
  console.log(a + ' <rest---> ' + args);
};

myfun(10, 20, 30, 40, 50);

//output - 10 <rest---> 20,30,40,50

💡 Note: Arrow function with return statement:

No parameter

If our function has just a single statement within the body then we can remove curly braces {} and we can also remove return keyword.

Example:

const getArrowvalue = () => 10;
console.log(getArrowvalue());

//output - 10

Here we have the fat arrow syntax. On the left hand side you have the parameter list to the function and on the right hand side you have an implicit return value.

So no parameters right now and we are returning 10.

Single parameter

const getArrowvalue = m => 10 * m;
console.log(getArrowvalue(5));

//output - 50

When you pass a single argument you can omit ():

few other examples;

var myfunN = c => c;             //work
var myfunN = c => {c};           //not work
var myfunN = c => {return c};    //work

Two or more parameter

But when you pass two or more argument then you need to keep ():

const getArrowvalue = (m, bonus) => 10 * m + bonus;
console.log(getArrowvalue(5, 50));

//output - 100

few other examples;

var myfunN = (a,b) => a+b;            //work
var myfunN = (a,b) => {a+b};          //not work - undefined
var myfunN = (a,b) => {return a+b};   //work

↥ back to top

Immediately invoked functions expression in JavaScript(IIFE)

  • IIFE (Immediately invoked function expression) is a JavaScript function that runs as soon as it is defined.
  • It is a design pattern which is also known as Self-Executing Anonymous Function.

💡 TIP: IIFE function is like an anonymous function only but it is self executing.

It means IIFE allows you to avoid creation of global variables and functions.

  • As it doesn’t define variables and functions globally so there will be no name conflicts.
  • Scope is limited to that particular function

Example:

(function () {
  console.log('Hello Sunil');
})();

//output - Hello Sunil

Here var is only limited to this function only. You can't access this variable outside of it.

Example(With variable):

(function () {
  var a = 10;
  console.log(a);
})();

//output - 10

Example(With parameter):

(function (a, b) {
  console.log(a, b);
})(30, 20);

//output - 30, 20

💡 TIP: IIFE function is self-executing


↥ back to top

Callback function

Any function that is passed as an argument is called a callback function.

In other words, A callback is a function that is to be executed after another function has finished executing — hence the name ‘call back’.

Simply put: Callbacks are a way to make sure certain code doesn’t execute until other code has already finished execution.

Call back function is of two types:

  • Synchronous : It waits for each operation to complete, after that it executes the next operation.
  • Asynchronous : It never waits for each operation to complete, rather it executes all operations in the first go only.

Example(Synchronous):

function show() {
  console.log('I am show function');
}
function geeky(callback) {
  callback();
}
geeky(show);
console.log('End');

//output - I am show function
//output - End

Example(Asynchronous):

setTimeout(function show() {
  console.log('I am show function');
}, 5000);

console.log('End');

//output - End
//output - I am show function

Example(without parameter):

function show() {
  console.log('I am show function');
}

function geeky(callback) {
  callback();
}
geeky(show);

//output - I am show function

Example(with parameter):

function show(a) {
  console.log('I am show function ' + a);
}

function geeky(callback) {
  var a = 101;
  callback(a);
}
geeky(show);

//output - I am show function 101

Example(Arrow function style):

function geeky(callback) {
  var a = 101;
  callback(a);
}
geeky((a) => console.log('I am show function ' + a));

//output - I am show function 101
References

↥ back to top

Object

An object is a collection of properties, and a property is an association between a name (or key) and a value.

A property’s value can be a function, in which case the property is known as a method.

💡 TIP: Objects are variables too. But objects can contain many values.


Declare and initialize an object in JavaScript

  • By using Object Literal
  • By using Object Constructor

Object Literal in JavaScript

Syntax:

var object_name = {};

Two ways you can write: [] or .

Example(using [] operator):

var fees = {};

fees['Rahul'] = 100;
fees['Sunil'] = 200;
console.log(fees['Rahul']);
console.log(fees['Sunil']);

//output - 100, 200

If you want to give a space between your property then you need to use double quote and try to access it via [] operator rather than . operator.

var fees = {};
fees['Sunil Pradhan'] = 100;

Example(using . operator):

var fees = {};

fees['Rahul'] = 100;
fees['Sunil'] = 200;
console.log(fees.Rahul);
console.log(fees.Sunil);

//output - 100, 200

Example(access methods):

var fees = {};
fees['total'] = function () {
  return 300;
};

fees.total(); //by using . operator
fees['total'](); //by using [] operator

console.log(fees.total());
console.log(fees['total']());

//output - 300, 300

Declare and initialization of object together:

Example:

var fees = {
  Rahul: 100,
  Sunil: 200,
  total: function () {
    return 300;
  },
};
console.log(fees.Rahul);
console.log(fees.Sunil);
console.log(fees.total());

//output - 100, 200, 300

↥ back to top

Object Constructor in JavaScript

Syntax:

var object_name = new Object();

Object() is a constructor which creates a reference of that object and it later assigns it to object_name. Then we write its properties and access it.

💡 TIP: A constructor is a function that initializes an object.


Two ways you can write: [] or .

Example(using [] operator):

var fees = new Object();

fees['Rahul'] = 100;
fees['Sunil'] = 200;
console.log(fees['Rahul']);
console.log(fees['Sunil']);

//output - 100, 200

If you want to give a space between your property then you need to use double quote and try to access it via [] operator rather than . operator.

var fees = new Object();
fees['Sunil Pradhan'] = 100;

Example(using . operator):

var fees = new Object();

fees['Rahul'] = 100;
fees['Sunil'] = 200;
console.log(fees.Rahul);
console.log(fees.Sunil);

//output - 100, 200

Example(access methods):

var fees = new Object();
fees['total'] = function () {
  return 300;
};

fees.total(); //by using . operator
fees['total'](); //by using [] operator

console.log(fees.total());
console.log(fees['total']());

//output - 300, 300

↥ back to top

Adding Object properties and methods in JavaScript

Syntax:

Object_name.Property_name = value;
Object_name['Property_name'] = value;

Example (add props):

var fees = {
  Sunil: 100,
  Anil: 200,
};

console.log(fees.Sunil + ' ' + fees.Anil);
fees.Rahul = 400; //added one props
console.log(fees);

//output - 100, 200
//output - { Sunil: 100, Anil: 200, Rahul: 400 }

Example (add methods):

var fees = {
  Sunil: 100,
  Anil: 200,
};

console.log(fees.Sunil + ' ' + fees.Anil);
fees.show = function () {
  return 300; // add methods
};
console.log(fees);
console.log(fees.show());

//output - 100, 200
//output - { Sunil: 100, Anil: 200, show: [Function (anonymous)] }
//output - 300

↥ back to top

Deleting Object properties and methods in JavaScript

Delete operator is used to delete instance properties.

Syntax:

delete object_name.property_name;

Example:

var fees = {
  Sunil: 100,
  Anil: 200,
};

console.log(fees.Sunil + ' ' + fees.Anil);

delete fees.Sunil;

console.log(fees.Sunil + ' ' + fees.Anil);
console.log(fees);

//output - 100, 200
//output - undefined 200
//output - { Anil: 200 }

After removal with the delete operator, the property has an undefined value.


↥ back to top

Factory function in JavaScript object

When a function returns an object, we call it a factory function. It can produce object instances without new keywords or classes.

function mobile() {
  return {
    model: 'iphone',
    price: function () {
      return 'Price - ₹1000';
    },
  };
}
var Apple = mobile();
console.log(Apple.model + ' ' + Apple.price());

//output - iphone Price - ₹1000

It looks like a simple function but in reality it isn’t. It is a factory function because it returns an object. Through this method we can create multiple object instances without using new keywords.

💡 TIP: Factory function reduces code repetition.

Example(with parameter):

function mobile(model_no) {
  return {
    model: model_no,
    price: function () {
      return 'Price - ₹1000';
    },
  };
}
var Apple = mobile('iphoneX');
console.log(Apple.model + ' ' + Apple.price());

var Apple = mobile('iphone 11');
console.log(Apple.model + ' ' + Apple.price());

//output - iphoneX Price - ₹1000
//output - iphone 11 Price - ₹1000

↥ back to top

Constructor in JavaScript

Object instances are created with constructor, which are basically special functions that prepare new instances of an object for use.

Remember:

  • Constructor is a special type of function that prepares a new instance of an object.
  • With factory functions you can create object instances in the same manner you can use constructor to create object instances.
  • When you are creating a constructor its first letter is always the capital letter.

Example:

function Mobile() {
  //write constructor name always capital
  this.model = 'iphoneX';
  //this points newly created object: example - iphonex
  this.price = function () {
    console.log(this.model + ' ' + 'Price - ₹1000');
  };
}

var Apple = new Mobile();
Apple.price();

//output - iphoneX Price - ₹1000

Globally this keyword points to window object but here this keyword points to a new instance of an object.

Remember:

Mobile() is a constructor whereas, price() is a function here.

Example(with parameter):

function Mobile(model_no) {
  //write constructor name always capital
  this.model = model_no;
  //this points newly created object: example - iphonex
  this.price = function () {
    console.log(this.model + ' ' + 'Price - ₹1000');
  };
}

var Apple = new Mobile('iphoneX');
Apple.price();

//output - iphoneX Price - ₹1000

This function is simply a constructor which behaves as a blueprint for all other mobile (samsung, lg). Because every mobile has a model, price and so.


↥ back to top

How to check properties exists in JavaScript

Method #1: By using typeof operator

function Mobile(model_no) {
  this.model = model_no;
  this.memory = 4;
}

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('3310');

if (typeof nokia.memory !== 'undefined') {
  console.log('Available');
} else {
  console.log('Does not exit');
}

//output - Available

This program checks whether memory properties present in our program or not.

Method #2: By using in operator

function Mobile(model_no) {
  this.model = model_no;
  this.memory = 4;
}

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('3310');

if ('memory' in nokia) {
  console.log('Available');
} else {
  console.log('Does not exit');
}

//output - Available

Method #3: By using hasOwnProperty()

function Mobile(model_no) {
  this.model = model_no;
  this.memory = 4;
}

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('3310');

if (nokia.hasOwnProperty('memory')) {
  console.log('Available');
} else {
  console.log('Does not exit');
}

//output - Available

↥ back to top

Object keys(object_name)

Example:

function Mobile(model_no) {
  this.model = model_no;
  this.color = 'white';
  this.ram = '4GB';
  this.price = function () {
    console.log(this.model + 'Price - ₹3000');
  };
}

var samsung = new Mobile('Galaxy');

console.log(Object.keys(samsung));

//output - [ 'model', 'color', 'ram', 'price' ]

Object keys only show object instance members (model, color) but can not show prototype members.

By using for..in loop, it shows both object instance members and prototype members.


↥ back to top

Array

Arrays are collections of data items stored under a single name.

Arrays provide a mechanism for declaring and accessing several data items with only one identifier, thereby simplifying the task of data management.

We use arrays when we have to deal with multiple data items.

Arrays are a special type of object in JavaScript.

Example:

var stu = ['Sunil', 'Anil', 'Rupa'];
console.log(stu);
console.log(typeof stu);

//output - [ 'Sunil', 'Anil', 'Rupa' ]
//output - object

In javascript you can create arrays in two ways:

  • Array literal
  • Array constructor

↥ back to top

Array Literal

Syntax:

var array_name = [];

💡 TIP: By default, array starts with index 0.

Example:

var stu = [];
//empty array
stu[0] = 'Sunil';
stu[1] = 'Rahul';
stu[2] = 'Anil';

console.log(stu); //access all array
console.log(stu[0]); //access Sunil

//output - [ 'Sunil', 'Rahul', 'Anil' ]
//output - Sunil

Example:

var stu = [, , , ,];
console.log(stu[0]);

//output - undefined

Example:

var a = 10,
  b = 20,
  c = 30;
var num = [a, b, c];
console.log(num);

//output - [ 10, 20, 30 ]

↥ back to top

Array Constructor

Syntax:

var array_name = new Array();

Example:

var stu = new Array();
//empty array

stu[0] = 'Sunil';
stu[1] = 'Rahul';
stu[2] = 'Rula';

console.log(stu);
console.log(stu[0]);

//output - [ 'Sunil', 'Rahul', 'Rula' ]
//output - Sunil

Demerits of using new keyword

Example:

var num = new Array(5);
console.log(num[0]);

//output - undefined

This will create an empty array with length five. So this is not a good idea to use an array constructor if you have only a single numeric value.


↥ back to top

Modifying array elements

Example:

var stu = ['Sunil', 'Ram'];
console.log(stu);

stu[0] = 'Rula';
console.log(stu);

//output - [ 'Sunil', 'Ram' ]
//output - [ 'Rula', 'Ram' ]

Example:

var stu = ['Sunil', 'Ram'];
var male = stu;
//storing array into a variable

console.log(male);
console.log(stu);

male[0] = 'Rula';
console.log(stu);

//output - [ 'Sunil', 'Ram' ]
//output - [ 'Sunil', 'Ram' ]
//output - [ 'Rula', 'Ram' ]

↥ back to top

Removing array elements

Array elements can be removed using the delete operator. This operator sets the array element it is invoked on to undefined but does not change the arrays’ length.

Example:

var stu = ['Sunil', 'Ram'];
console.log(stu);
delete stu[0];
console.log(stu);

//output - [ 'Sunil', 'Ram' ]
//output - [ undefined, 'Ram' ]

↥ back to top

Array length property

The length property retrieves the index of the next available position at the end of the array. The length property is automatically updated as new elements are added to the array. For this reason, length is commonly used to iterate through all elements of any array.

💡 TIP: In array index it counts from 0 but in array length property it counts from 1.

var stu = ['Sunil', 'Ram'];
console.log(stu.length);

//output - 2

↥ back to top

Iteration of array using for loop

Example:

var stu = ['Sunil', 'Ram', 56, 66];
for (let i = 0; i <= 3; i++) {
  console.log(stu[i]);
}

//output - Sunil, Ram, 56 , 66

Example:

var stu = ['Sunil', 'Ram', 56, 66];
for (let i = 0; i <= stu.length - 1; i++) {
  console.log(stu[i]);
}

//output - Sunil, Ram, 56 , 66

↥ back to top

forEach Loop

The forEach loop calls a provided function once for each element in an array, in order.

In other words,

ES6 provides the forEach loop to iterate over array elements. So let's say we have an array of numbers 2, 4, 6, 8 then we can call the forEach loop on this numbers array by passing a function.

Syntax:

array.forEact(function (value, index, arr) {});

Where,

  • value - It is the current value of array index and it's a variable so that you can name it anything like value, name or other. It is mandatory.
  • index - Array's index number. Here also you can give any other name index, i or any other. It is not mandatory.
  • arr - The array object the current element belongs to. It is not mandatory.

Example:

var stu = ['Sunil', 'Ram', 56, 66];
stu.forEach(function (name) {
  console.log(name);
});

//output - Sunil, Ram, 56, 66

Example:

var stu = ['Sunil', 'Ram', 56, 66];
stu.forEach(function (value, index) {
  console.log(value, index);
});

//output - Sunil 0
//output - Ram 1
//output - 56 2
//output - 66 3

forEach loop worked out pretty well with arrays but from ES6 you can use forEach with maps and sets too.

So over here we have created a new map and this contains two key value pairs first name Sunil and last name Pradhan.

let myMap = new Map([
  ['fname', 'Sunil'],
  ['lname', 'Pradhan'],
]);

myMap.forEach(mapFunction);
function mapFunction(value, key, callingMap) {
  console.log(key + ' ' + value);
  console.log(myMap === callingMap);
}

//output - fname Sunil
//output - true
//output - lname Pradhan
//output - true

Similar to arrays we call the forEach loop on the map and we have a function passed into the parentheses.

Now this map function is going to again accept three parameters, the value so Sunil and Pradhan, the key fname and lname.

And then the callingMap, so the map on which the forEach method is called.

So that is how the forEach loop works with maps now, similarly we also have the forEach loop with sets:

Just create a new set and it has three unique values 1 2 & 3.

Again we are calling the forEach loop on mySet by passing a function called set function.

And the set function is going to accept three parameters again: value, key and callingSet.

let mySet = new Set([1, 2, 3]);
mySet.forEach(setFunction);
function setFunction(value, key, callingSet) {
  console.log(key + ' ' + value);
  console.log(mySet === callingSet);
}

//output - 1 1
//output - true
//output - 2 2
//output - true
//output - 3 3
//output - true

So in sets the key and value are both the same but we have those three parameters here, because they wanted to maintain the standard across arrays, maps and sets.

Now if you have a look array has three parameters, map has three parameters and they wanted to continue the same and that is why they have three parameters even for a set.

So the key and value are going to be the same. You can just log out either one of them and when we do a mySet triple equal to the callingSet we have true.


↥ back to top

MultiDimensional array

Multidimensional array is Arrays of Arrays.In other words, an array that contains an array is called a multidimensional array.

Multidimensional array can be 2D, 3D, 4D etc.

2D Array Example:

var name[[], [], []];
Student Computer Qt.
Rahul Dell 10
Sonam HP 20
Sumit Zen 30

In computer memory:

Student Computer Qt.
[0][0]Rahul [0][1]Dell [0][2]10
[1][0]Sonam [1][1]HP [1][2]20
[2][0]Sumit [2][1]Zen [2][2]30

Example:

var stu = [
  ['Sunil', 'Dell', 10],
  ['Anil', 'HP', 20],
  ['Rula', 'Zen', 50],
];

//for rows
for (let i = 0; i < 3; i++) {
  //for coloumns
  for (let j = 0; j < 3; j++) {
    console.log(stu[i][j]);
  }
}

//output - Sunil, Dell, 10
//output - Anil, HP, 20
//output - Rula, Zen, 50

↥ back to top

Array Methods

concat() Method

Syntax:

new_array = old_array.concat(value1, value2, value_n);

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.

Example(concat with new values):

var stu = ['Sunil', 'Hari', 'Ram'];
//concat values
var new_stu = stu.concat('Rula', 'Hari');
console.log(new_stu);

//output - [ 'Sunil', 'Hari', 'Ram', 'Rula', 'Hari' ]

Example(merge two arrays and make a new array):

var stu1 = ['Sunil', 'Ram', 'Sumit'];
var stu2 = ['Raj', 'Rohan'];

var new_stu = stu1.concat(stu2);
console.log(new_stu);

//output - [ 'Sunil', 'Ram', 'Sumit', 'Raj', 'Rohan' ]

Example(merge three arrays and make a new array):

var stu1 = ['Sunil', 'Ram', 'Sumit'];
var stu2 = ['Raj', 'Rohan'];
var stu3 = ['Pinku'];

var new_stu = stu1.concat(stu2, stu3);
console.log(new_stu);

//output - [ 'Sunil', 'Ram', 'Sumit', 'Raj', 'Rohan', 'Pinku' ]

↥ back to top

join() Method

The join() method joins the elements of an array into a string, and returns the string. The elements will be separated by a specified separator. The default separator is comma ,.

Syntax:

array_name.join(separator);

Example:

var stu = ['Sunil', 'Ram'];
var new_stu = stu.join(' / ');
console.log(stu);
console.log(new_stu);

//output - [ 'Sunil', 'Ram' ]
//output - Sunil / Ram

↥ back to top

reverse() Method

The reverse() method reverses the order of the elements in an array.

Syntax:

array_name.reverse();

Example:

var stu = ['Sunil', 'Anil'];
console.log(stu);
stu.reverse();
console.log(stu);

//output - [ 'Sunil', 'Anil' ]
//output - [ 'Anil', 'Sunil' ]

↥ back to top

slice() Method

The slice() method returns a shallow copy of a portion of an array into a new array object selected from beginning to end(end not included). The original array will not be modified.

Syntax:

array_name.slice(start, end);

Remember:

  • Returns a portion of the array as a second array
  • Does not modify the array
  • First argument specifies starting element
  • Second argument specifies ending argument
  • Second argument is optional

Start:

  • If begin is undefined, slice begins from index 0.
  • If the beginning is greater than the length of the sequence, an empty array is returned.
  • A negative index can be used, indicating an offset from the end of the sequence. slice(-2) extracts the last two elements in the sequence.

End:

  • If the end is omitted, slice extracts through the end of the sequence(arr.length).
  • If the end is greater than the length of the sequence, slice extracts through to the end of the sequence (arr.length).
  • A negative index can be used, indicating an offset from the end of the sequence. slice(2,-1) extracts the third element through the second-to-last element in the sequence.

Example(start, end):

var arr = [1, 2, 3, 4, 5, 6];
var arr1 = arr.slice(0, 2);
console.log(arr1);

//output - [ 1, 2 ]

Here 0 is the starting point and position 2 is the end point but it is not included.

Example(start):

var arr = [1, 2, 3, 4, 5, 6];
var arr1 = arr.slice(2);
console.log(arr1);

//output - [ 3, 4, 5, 6 ]

Example(negative value - start):

var stu = ['Sanjay', 'Aman', 'Rehman', 'Rahul', 'Karan'];
console.log(stu);

var new_stu = stu.slice(-3);
console.log(new_stu);

//output - [ 'Sanjay', 'Aman', 'Rehman', 'Rahul', 'Karan' ]
//output - [ 'Rehman', 'Rahul', 'Karan' ]

In memory:

'Sanjay' ->5, 'Aman' ->4, 'Rehman'-> -3, 'Rahul'-> -2, 'Karan' -> -1

Example(negative value - start, end):

var stu = ['Sanjay', 'Aman', 'Rehman', 'Rahul', 'Karan'];
console.log(stu);

var new_stu = stu.slice(-3, -1);
console.log(new_stu);

//output - [ 'Sanjay', 'Aman', 'Rehman', 'Rahul', 'Karan' ]
//output - [ 'Rehman', 'Rahul' ]

↥ back to top

splice() Method

The splice() method changes the contents of an array by removing existing elements and/or adding new elements. This method changes the original array.

Syntax:

array_name.splice(start, delete_count, replace_values);

Start - The first argument start specifies at what position to add/remove items, use negative values to specify the position from the end of the array.

delete_count - The second argument “delete_count”, is the number of elements to delete beginning with index start.

replace_values - “replace_values” are inserted in place of the deleted elements. If more than one separates it by comma.

Remember:

  • Modifies the array on which it is invoked
  • The first argument specifies the array postion for insertion or deletion
  • The second argument indicates the number of elements to delete
  • The deleted elements are returned as an array
  • The second argument is optional
  • Each additonal argument is inserted into the array

Example:

var arr = [1, 2, 3, 4, 5, 6];
//delete few elements:

var arr1 = arr.splice(2, 2);
console.log(arr1);

//check old array
console.log(arr);

//output - [ 3, 4 ]
//output - [ 1, 2, 5, 6 ]

Example:

var arr = [1, 2, 3, 4, 5, 6];
//delete few elements:

var arr1 = arr.splice(2, 2);
console.log(arr1);

//doesn't find any element
var arr2 = arr.splice(4);
console.log(arr2);

//check old array
console.log(arr);

//output - [ 3, 4 ]
//output - []
//output - [ 1, 2, 5, 6 ]

Example:

var arr = [1, 2, 3, 4, 5, 6];
//inserting

let arr3 = arr.splice(2, 0, 'a', 'b');

console.log(arr3);
console.log(arr);

//output - []
//output - [
//          1, 2, 'a', 'b',
//          3, 4, 5,   6
//         ]

Example:

var arr = [1, 2, 3, 4, 5, 6];
//inserting & deleting both

let arr4 = arr.splice(2, 1, 'a', 'b');

console.log(arr4);
console.log(arr);

//output - [3]
//output - [
//          1, 2, 'a', 'b',
//          4, 5, 6
//         ]

Example:

var a = ['Sanjay', 'Aman', 'Rehman', 'Rahul'];

console.log(a);

a.splice(-2, 1, 'Neha', 'Karan');
//negative
console.log(a);

//output - [ 'Sanjay', 'Aman', 'Rehman', 'Rahul' ]
//output - [ 'Sanjay', 'Aman', 'Neha', 'Karan', 'Rahul' ]

↥ back to top

toString() Method

The toString() Method returns a string containing the comma-separated values of the array. This method is invoked automatically when you print an array.

It is equivalent to invoking join() method without any arguments. The returned string will separate the elements in the array with commas.

Syntax:

array_name.toString();

Example:

var stu = ['Sunil', 'Ram', 'Gopal'];
stu.toString();
console.log(stu);

//output - [ 'Sunil', 'Ram', 'Gopal' ]

↥ back to top

Array.isArray() Method

The Array.isArray() method determines whether the passed value is an Array. This function returns true if the object is an array, and false if not.

Syntax:

Array.isArray(value);

Example:

var result1 = Array.isArray(['Rahul', 'Sonam']);
console.log(result1);

//output - true

var result2 = Array.isArray('I am String');
console.log(result2);

//output - false

↥ back to top

indexOf() Method

This method allows you to easily find the occurrence of an item in an array.

  • If the item is not found, it returns -1
  • The search will start at the specified position, or at the beginning if no start position is specified, and end the search at the end of the array.
  • If the item is present more than once, the indexOf method returns the position of the first occurrence.

Syntax:

var position = array_name.indexOf(item, start);

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

var position = stu.indexOf('Sunil');
console.log(position);

//output -1

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

var position = stu.indexOf('Sumit');
console.log(position);

//output - 2

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

var position = stu.indexOf('Raj');
console.log(position);

//output - 3

↥ back to top

fill() Method

The fill() method fills all the elements in an array with a static value.

Syntax:

array_name.fill(value, start, end);

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

stu.fill('Manu');

//no start and no end
console.log(stu);

//output - [ 'Manu', 'Manu', 'Manu', 'Manu', 'Manu' ]

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

stu.fill('Manu', 1, 3);

//fill Manu starting with index 1 to 3 but 3 not included
console.log(stu);

//output - [ 'Rahul', 'Manu', 'Manu', 'Raj', 'Raj' ]

↥ back to top

unshift() Method

The unshift() method adds one or more elements to the beginning of an array and returns the new length of the array.

This method changes the length of an array.

Syntax:

Array_name.unshift(value1, value2, value_n);

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

stu.unshift('Sunil');
console.log(stu);

//output - [ 'Sunil', 'Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj' ]

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

var stu_length = stu.unshift('Sunil');
console.log(stu);
console.log(stu_length);

//output - [ 'Sunil', 'Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj' ]
//output - 6

↥ back to top

push() Method

The push() method adds one or more elements to the end of an array and returns the new length of the array.

The new item will be added at the end of the array.

This method changes the length of the array.

Syntax:

Array_name.push(value1, value2, value_n);

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

stu.push('Sunil');
console.log(stu);

//output - [ 'Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj', 'Sunil' ]

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

var stu_length = stu.push('Sunil');
console.log(stu);
console.log(stu_length);

//output - [ 'Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj', 'Sunil' ]
//output - 6

↥ back to top

shift() Method

The shift() method removes the first element from an array and returns that removed element. This method changes the length of the array.

Syntax:

array_name.shift();

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

stu.shift();
console.log(stu);

//output - [ 'Sonam', 'Sumit', 'Raj', 'Raj' ]

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

var stu_removed = stu.shift();
console.log(stu);
console.log(stu_removed);

//output - [ 'Sonam', 'Sumit', 'Raj', 'Raj' ]
//output - Rahul

↥ back to top

pop() Method

The pop() method removes the last element from an array and returns that removed element. This method changes the length of the array.

Syntax:

array_name.pop();

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

stu.pop();
console.log(stu);

//output - [ 'Rahul', 'Sonam', 'Sumit', 'Raj' ]

Example:

var stu = ['Rahul', 'Sonam', 'Sumit', 'Raj', 'Raj'];

var stu_removed = stu.pop();
console.log(stu);
console.log(stu_removed);

//output - [ 'Rahul', 'Sonam', 'Sumit', 'Raj' ]
//output - Raj

↥ back to top

Boolean() Method

Boolean is the built-in object corresponding to the primitive Boolean data type. JavaScript boolean can have one of two values: true or false.

Primitive values:

var primitiveTrue = true;
var primitiveFalse = false;

Boolean function:

var functionTrue = Boolean(true);
var functionFalse = Boolean(flase);

Boolean constructor:

var constructorTrue = new Boolean(true);
var constructorFalse = new Boolean(false);

Example:

var a = Boolean(); //false
var a = Boolean(0); //false
var a = Boolean(-0); //false
var a = Boolean(NaN); //false
var a = Boolean(null); //false

↥ back to top

includes() Method

The includes() method determines whether an array contains a specified element.

This method returns true if the array contains the element, and false if not. The includes() method is case sensitive.

Syntax:

array.includes(element, start);

Example:

var fruits = ['Banana', 'Orange', 'Apple', 'Mango'];
var n = fruits.includes('Mango');
console.log(n);

//output - true
Reference

↥ back to top

sort() Method

The sort() method sorts the items of an array.

Syntax:

array.sort(compareFunction);

Example:

var fruits = ['Banana', 'Orange', 'Apple', 'Mango'];
console.log(fruits.sort());

//output - [ 'Apple', 'Banana', 'Mango', 'Orange' ]
Reference

↥ back to top

String

String is a group of characters.

var name = 'Sunil';
console.log(name);
console.log(typeof name);

//output - Sunil
//output - String

Store a string value in a variable:

Example(Primitive):

var str = 'Hello World!';
console.log(typeof str);

//output - string

Example(Constructor):

var str = new String('Hello World');
console.log(typeof str);

//output - object

Access string value:

Example(Primitive):

var str = 'Hello World!';
console.log(str);

//output - Hello World!

Example(Constructor):

var str = new String('Hello World');
console.log(str);

//output - Hello World!

↥ back to top

String Concatenation

Connect two different strings and make it one.

Example(+ operator):

var str1 = 'Hello';
var str2 = ' Sunil';

console.log(str1 + str2);

//output - Hello Sunil

Example(concat() method):

The concat() method accepts any number of arguments and returns the string obtained by concatenating the arguments to the string on which it was invoked.

Syntax:

string.concat(string1, string2, string_n);
var new_str = 'A'.concat('B', 'C');
console.log(new_str);

var str1 = 'Hello';
var str2 = ' World!';
var str3 = ' ABC';
var new_str = str1.concat(str2, str3, ' XY');
console.log(new_str);

//output - ABC
//output - Hello World! ABC XY

↥ back to top

Template Literal/String Templates

Template literals allow us to embed expressions. You can use multi-line strings and string interpolation features with them.

Template literals are enclosed by the back-tick (` `) character instead of double or single quotes.

Example:

var user = 'Sunil';

var greet = `Welcome ${user} to ES6 course!`;
console.log(greet);

//output - Welcome Sunil to ES6 course!

If you want to use a value that is assigned to a variable within a string we can use the dollar$ and wrap the variable name within curly braces.

💡 TIP: String Interpolation - Template literals can contain placeholders. These are indicated by the dollar sign and curly braces ${expression}.


String template also allows you to use single quotes and double quotes within the string.

Example:

var user = 'Sunil';

var greet = `Welcome 'single' "double" ${user} to ES6 course!`;
console.log(greet);

//output - Welcome 'single' "double" Sunil to ES6 course!

String template also supports multi-line strings so now you can have multiple lines without having to use the string concatenation.

Example:

var user = 'Sunil';

var greet = `Welcome 'single' "double" ${user} to ES6 course!
              This is the second line.
              Third and so   on.
`;
console.log(greet);

//output - Welcome 'single' "double" Sunil to ES6 course!
//This is the second line.
//Third and so   on.

↥ back to top

String length

The length property returns the length of a string

Example:

var str = 'Sunil Pradhan';
console.log(str.length);
//including space

//output - 13

↥ back to top

String Methods

charAt() Method

The charAt() method returns the character at a specified index (position) in a string.

Example:

var str = 'Hello Sunil';
console.log(str.charAt(9));

//output - i

↥ back to top

charCodeAt() Method

The charCodeAt() method returns the unicode of the character at a specified index in a string.

var str = 'Hello Sunil';
console.log(str.charCodeAt(9));

//output - 105

↥ back to top

toUpperCase() & toLowerCase() Method

Convert string to uppercase and lowercase.

Example:

var str = 'Hello Sunil';
console.log(str.toUpperCase());

//output - HELLO SUNIL

Example:

var str = 'Hello Sunil';
console.log(str.toLowerCase());

//output - hello sunil

↥ back to top

trim() Method

It removes white space from both side of string (starting and ending part only).

Example:

var str = '      Hello Sunil    ';
console.log(str.trim());

//output - Hello Sunil

↥ back to top

replace() Method

The replace() method replaces a specified value with another value in a string, replace() method replaces only the first match.

  • replace (old, new) method
  • case sensitive this method
  • It's good to use in reg. expression

Example:

var str = 'Hello Sunil';
console.log(str.replace('Sunil', 'World'));

//output - Hello World

↥ back to top

split() Method

The split() method breaks the string up into a separate string according to a delimiter passed as its first argument. The result is returned in an array.

Example:

var str = 'Hello';
console.log(str.split(''));

//output - [ 'H', 'e', 'l', 'l', 'o' ]

Example:

var str = 'Hello World, I am Sunil';
console.log(str.split(','));

//output - [ 'Hello World', ' I am Sunil' ]

Example:

var str = 'Hello World, I am Sunil';
var arr = str.split(' ');
console.log(arr[4]);

//output - Sunil

↥ back to top

indexOf() Method

The indexOf() method takes a string argument and returns the index of the first occurance of the argument in a string. If the argument is not found returns -1.

This method also accepts an optional second argument that specifies the index at which to start the search.

Example:

var str = 'Hi guys! I am Sunil';
console.log(str.indexOf('i'));
console.log(str.indexOf('i', 10));

//output - 1
//output - 17

↥ back to top

search() Method

The search() method searches for a string for a specified value and returns the position of the match.

The search() method cannot take a second start position argument. It can use in reg. expression and bit advance of indexOf().

Example:

var str = 'Hi guys! I am Sunil';
console.log(str.search('i'));

//output - 1

↥ back to top

slice() Method

The slice() extracts a part of a string and returns the extracted part in a new string.

The method takes two parameters: the starting index(position), and the ending index(position). The method returns a string containing the string beginning at the given index up to but not including the character at the index specified by the second argument.

If a parameter is negative, the position is counted from the end of the string.

Example:

var str = 'Hi guys! I am Sunil';
console.log(str.slice(14, 19));

//output - Sunil

↥ back to top

substring() Method

The substring() is similar to slice(). The first argument specifies the index at which the desired substring begins. The optional second argument indicates the index at which the desired substring ends.

The method returns a string containing the substring beginning at the given index up to but not including the character at the index specified by the second argument.

The difference between slice and substring is that substring() cannot accept negative indexes.

Example:

var str = 'Hi guys! I am Sunil';
console.log(str.substring(14, 19));

//output - Sunil

↥ back to top

substr() Method

The substr() is similar to slice(). The substr() method returns the part of a string between the start index and a number of characters after it.

substr() extracts length characters from a string, counting from the start index. If the start is a positive number, the index starts counting at the start of the string. If the start is a negative number, the index starts counting from the end of the string.

Example:

var str = 'Hi guys! I am Sunil';
console.log(str.substr(14, 19));

//output - Sunil

↥ back to top

Number

Number type in JavaScript includes both integer and floating point values. JavaScript numbers are always stored as double precision floating point numbers, following the international IEEE 754 standard.

JavaScript also provides an object representation of numbers.

Example(Primitive):

//typeof - number

var a = 10; //Whole number
var a = 10.45; //Decimal number
var a = 5e3; //5000 - 5x10^3 exponent
var a = 34e-5; //0.00034 exponent

Example(Constructor):

//typeof - Object

var a = new Number(10);
var a = new Number(10.45);
var a = new Number(5e3);

Accessing number:

Example:

var a = 10;
console.log(a);
console.log(typeof a);

//output - 10
//output - number

Example:

var x = new Number(100);
console.log(x);
console.log(typeof x);

//output - 100
//output - object

↥ back to top

Number with String

Example:

var a = '50';
var b = 10;
console.log(a + b);
console.log(typeof a, typeof b);

//output - 5010
//output - string number

↥ back to top

NaN - Not a Number

The NaN property represents “Not-a-Number” value. This property indicates that a value is not a legal number. NaN never compares equal to anything, even itself.

The NaN property is the same as the Number.

Example:

var c = 20; //number
var d = 'Hello'; //string
console.log(c / d);

//output - NaN

NaN is not equal to anything in JavaScript:

Example:

if ('Hello' == NaN) {
  console.log('Equal');
} else {
  console.log('Not equal');
}

//output - Not equal

Example:

if (NaN == NaN) {
  console.log('Equal');
} else {
  console.log('Not equal');
}

Global isNaN() Method:

  • The isNaN() function is used to determine whether a value is an illegal number (Not-a-Number).
  • This function returns true if the value equates to NaN. Otherwise it returns false.
  • This function is different from the Number specific Number.isNaN() method.
  • The global isNaN() function, converts the tested value to a Number, then tests it.

Example:

var a = '50';
if (isNaN(a)) {
  console.log('Not a number');
} else {
  console.log('Legal number');
}

//output - Legal number

↥ back to top

Infinity and Negative Infinity

Infinity or -Infinity is the value JavaScript will return if a number is too large or too small. All infinity values compare equal to each other.

Example:

console.log(5 / 0); //Infinity
console.log(-5 / 0); //-Infinity

↥ back to top

Number Methods

toString() Method

toString() method returns a number as a string in other words it converts the number into string.

We can use this method to output numbers as hexadecimal(16), octal(8), binary(2).

Example:

var a = 10;
console.log(typeof a);
console.log(a.toString());
console.log(typeof a.toString());

//output - number
//output - 10
//output - string

Example:

var a = 10;
console.log(typeof a);
console.log(a.toString(2));
console.log(a.toString(8));
console.log(a.toString(16));

//output - number
//output - 1010
//output - 12
//output - a

↥ back to top

toExponential() Method

The toExponential() method converts a number into an exponential notation.

Syntax:

variable_name.toExponential(y);

Where y is an integer between 0 and 20 representing the number of digits in the notation after the decimal point. If omitted, it is set to as many digits as necessary to represent the value.

Example:

var a = 58975.98745;
console.log(a.toExponential());
console.log(a.toExponential(2));
console.log(a.toExponential(4));

//output - 5.897598745e+4
//output - 5.90e+4
//output - 5.8976e+4

↥ back to top

toFixed() Method

toFixed() method converts a number into a string, keeping a specified number of decimals; also it rounds the decimal. If the desired number of decimals are higher than the actual number, nulls are added to create the desired decimal length.

Syntax:

a.toFixed(y);

Where y is the number of digits after the decimal point. Default is 0 (no digits after the decimal point).

Example:

var a = 19.65823;
console.log(a.toFixed());
console.log(a.toFixed(2));
console.log(a.toFixed(3));

//output - 20
//output - 19.66
//output - 19.658

↥ back to top

toPrecision() Method

toPrecision() method formats a number to a specified length. A decimal point and nulls are added (if needed), to create the specified length.

Syntax:

variable_name.toPrecision(y);

Where y is the number of digits. If omitted, it returns the entire number (without any formatting)

Example:

var a = 19.65823;
console.log(a.toPrecision());
console.log(a.toPrecision(2));
console.log(a.toPrecision(3));

//output - 19.65823
//output - 20
//output - 19.7

↥ back to top

isInteger() Method

Number.isInteger() method determines whether a value is an integer or not.

This method returns true if the value is of the type Number, and an integer, Otherwise it returns false.

Example:

console.log(Number.isInteger());
console.log(Number.isInteger(100));
console.log(Number.isInteger(-100));
console.log(Number.isInteger(100.45));
console.log(Number.isInteger(200 - 100));

//output - false
//output - true
//output - true
//output - false
//output - true

↥ back to top

isSafeInteger() Method

Number.isSafeInteger() method determines whether a value is a safe integer.

A safe integer is an integer that can be exactly all integers from (253 - 1) to - (253 - 1).

This method returns true if the value is of the type Number, and a safe integer. Otherwise it returns false.

Example:

console.log(Number.isSafeInteger(100));
console.log(Number.isSafeInteger(-100));
console.log(Number.isSafeInteger(0.1));

//output - true
//output - true
//output - false

↥ back to top

Global JavaScript methods

Global JavaScript methods can be used on all JavaScript data types.

  • Number()
  • parseInt()
  • parseFloat()

Number() - The Number() function converts the object argument to a number that represents the object’s value.

If the value can’t be converted to a legal number, NaN is returned.

If the parameter is a Date object, the Number() function returns the number of milliseconds since midnight January 1, 1970 UTC.

Example:

console.log(Number(true));
console.log(Number('100'));
console.log(Number(100 / 'Hello'));

//output - 1
//output - 100
//output - NaN

Example:

var f = new Date();
console.log(Number(f));

//output - 1591545077754

parseInt() - The parseInt() function parses a string and returns an integer.

Syntax:

parseInt(string, radix);

Example:

console.log(parseInt('10'));
console.log(parseInt('10.45'));
console.log(parseInt('10 20 30'));

//output - 10
//output - 10
//output - 10

parseFloat() - The parseFloat() function parses a string and returns a floating point number. This function determines if the first character in the specified string is a number.

If it is, it parses the string until it reaches the end of the number, and returns the number as a number, not as a string.

Syntax:

parseFloat(string);

Example:

console.log(parseFloat('10'));
console.log(parseFloat('10.45'));
console.log(parseFloat('10 20 30'));

//output - 10
//output - 10.45
//output - 10

↥ back to top

Math object

The Math object holds a set of constants and methods that enable more complex mathematical operations than the basic arithmetic operators.

We can not instantiate a Math Object. The Math object is static so it’s properties and methods are accessed directly.

console.log(Math.PI);

//output - 3.141592653589793

Min() and Max() Method:

Min() - find minimum value Max() - find maximum value

Example:

console.log(Math.min(50, 5, 90, 6));
console.log(Math.max(50, 5, 90, 6));

//output - 5
//output - 90

floor() Method:

The floor() method rounds a number downwards to the nearest integer, and returns the result.

Example:

console.log(Math.floor(2.1));
console.log(Math.floor(6.65));
console.log(Math.floor(0.4));
console.log(Math.floor(-2.1));
console.log(Math.floor(-6.65));

//output - 2
//output - 6
//output - 0
//output - -3
//output - -7

round() Method:

The round() method rounds a number to the nearest integer. 6.4 will be rounded down, 6.5 will be rounded up.

Example:

console.log(Math.round(2.1));
console.log(Math.round(6.65));
console.log(Math.round(0.4));
console.log(Math.round(-2.1));
console.log(Math.round(-6.65));

//output - 2
//output - 7
//output - 0
//output - -2
//output - -7

💡 TIP: floor and round is used when you are dealing with price or need to create a random number.

random() Method:

It generate random number.

Example:

console.log(Math.random() * 100 + 1);
var x = Math.floor(Math.random() * 100 + 1);
console.log(x);

//output - 54.631881910377864
//output - 81
Reference

https://www.w3schools.com/jsref/jsref_obj_math.asp

sqrt(a) Method:

It returns square root of a number.

Example:

var x = 25;
Math.sqrt(x);

//output - 5

pow(a,b) Method:

It returns value of a to the power b.

Example:

var x = 25;
var y = 2;
Math.pow(x, y);

//output - 625

↥ back to top

Date object

The date object provides a sophisticated set of methods for manipulating dates and times.

  • It reads the client machine date and time so if the client’s date or time is incorrect, your script will reflect this fact.
  • Days of week and months of the year are enumerated beginning with zero.

0 - Sunday, 1 - Monday and so on. 0 - January, 1 - February and so on.


↥ back to top

Creating date object

Date objects are created with the new Date() constructor. Date Objects created by programmers are static. They do not contain a ticking clock.

Syntax:

new Date();
new Date(milliseconds);
new Date(year, month, day, hours, minutes, seconds, milliseconds);
new Date(dateString);

Create Date object using Date():

new Date() creates a new date object with the current date and time.

Example:

var today = new Date();
console.log(today);

//output - 2020-06-08T16:02:40.621Z

Create Date object using Date(millisecond):

new Date(millisecond) - It creates a new date object as January 1,1970, 00:00:00 Universal Time (UTC).

Example:

var today = new Date(1530867166586);
console.log(today);

//output - 2018-07-06T08:52:46.586Z

It is used for converting milliseconds to normal date format.

Create Date object using Date(year, month, day, hours, minutes, seconds, milliseconds):

It creates an object with the date specified by the integer values for the year, month, day, hours, minutes, second, milliseconds. You can omit some of the arguments.

Example:

var today = new Date(2020, 4, 25, 9, 45, 35, 0);
console.log(today);

//output - 2020-05-25T04:15:35.000Z

Month and Week day start with 0.

0 - Sunday 0 - January

Month day starts with 1

1 - 1

Create Date object using Date(dateString):

new Date(dateString) - It creates a new date object from a date string.

Example:

var today = new Date('May 12, 2020 10:16:05');
console.log(today);

//output - 2020-05-12T04:46:05.000Z

It is divided into three category:

Date Type Formate Example
ISO Date YYYY-MM-DD 2020-06-21 (The International Standard)
Short Date MM/DD/YYYY 06/21/2020
Long Date MMM DD YYYY June 21 2020 or 21 June 2020

ISO Date:

ISO 8601 is the international standard for the representation of dates and times.

Description Formate Example
Year and Month YYYY-MM 2020-06
Only Year YYYY 2020
Date and Time YYYY-MM-DDTHH:MM:SSZ 2020-06-21T12:00:00Z
  • Date and Time is separated with a capital T
  • UTC time is defined with a capital letter Z
  • If you want to modify the time relative to UTC, remove the Z and add +HH:MM or -HH:MM instead

Example:

var today = new Date('2020-06');
console.log(today);

//output - 2020-06-01T00:00:00.000Z

Short Date:

  • Short dates are written with an 'MM/DD/YYYY' format.
  • In some browsers, months or days with no leading zeroes may produce an error.
  • The behavior of 'YYYY/MM/DD' is undefined. Some browsers will try to guess the format.Some will return NaN.
  • The behavior of 'DD-MM-YYYY' is also undefined. Some browsers will try to guess the format. Some will return NaN.

Example:

var today = new Date('06-12-2020');
console.log(today);

//output - 2020-06-11T18:30:00.000Z

Long Date:

  • Long dates are most often written with a 'MMM DD YYYY' format.
  • Month and day can be in any order.
  • Month can be written in full(January), or abbreviated(Jan).
  • If you write 'June, 21, 2020' commas are ignored and Names are case insensitive.

Example:

var today = new Date('Mar 25 2020');
console.log(today);

//output - 2020-03-24T18:30:00.000Z

↥ back to top

Set Date Methods

This is used to set date.

  • setDate() - Set the day as a number (1-31)
  • setFullYear() - Set the year (optionally month and day)
  • setHours() - Set the hour(0-23)
  • setMilliseconds() - Set the milliseconds (0-999)
  • setMinutes() - Set the minutes (0-59)
  • setMonth() - Set the month (0-11)
  • setSecond() - Set the seconds(0-59)
  • setTime() - Set the time(milliseconds since January 1, 1970)

↥ back to top

Get Date Methods

This is used to get date.

  • getFullYear() - Get the year as a four digit number (yyyy)
  • getMonth() - Get the month as a number (0-11)
  • getDate() - Get the day as a number(1-31)
  • getHours() - Get the hour(0-23)
  • getMinutes() - Get the minute (0-59)
  • getSeconds() - Get the second (0-59)
  • getMilliseconds() - Get the millisecond (0-999)
  • getTime() - Get the time (millisecond since January 1, 1970)
  • getDay() - Get the weekday as a number(0-6)

↥ back to top

Retrieve Month name and Day name

For month:

var tarikh = new Date();
var month = tarikh.getMonth();
var day = tarikh.getDay();

console.log(getMonthName(month));

function getMonthName(monthnumber) {
  var monthname = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December',
  ];

  return monthname[monthnumber];
}

//output - June

For day:

var tarikh = new Date();
var month = tarikh.getMonth();
var day = tarikh.getDay();

console.log(getDayName(day));

function getDayName(daynumber) {
  var dayname = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday',
  ];

  return dayname[daynumber];
}

//output - Monday

↥ back to top

Format Date and Time

Example:

var tarikh = new Date();
console.log(formateDate(tarikh));

function formateDate(pd) {
  var date = pd.getDate();
  var month = pd.getMonth();
  month++;
  var year = pd.getFullYear();
  return date + '-' + month + '-' + year;
}

//output - 8-6-2020

↥ back to top

Convert Date to String

If you want to create a string in a standard format, Date provides three methods: -

  • toString()
  • toUTCString()
  • toGMTString()

toUTCString() and toGMTString() format the string according to Internet (GMT) standards, whereas toString() creates the string according to local time.

Example:

var today = new Date();
console.log(today.toString());
console.log(today.toUTCString());
console.log(today.toGMTString());

//output - Mon Jun 08 2020 22:38:27 GMT+0530 (India Standard Time)
//output - Mon, 08 Jun 2020 17:08:27 GMT
//output - Mon, 08 Jun 2020 17:08:27 GMT

↥ back to top

Prototype

By prototype, write once the code, it will be available for you to use on all other objects.

Syntax:

classname.prototype.key = 'value';

Let's take one example:

var Mobile = function (model_no) {
  this.model = model_no;
  this.price = 3000;
};

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('G8');

//add a new object
samsung.color = 'White';
nokia.color = 'White';
console.log(samsung);
console.log(nokia);

//output - Mobile { model: 'Galaxy', price: 3000, color: 'White' }
//output - Mobile { model: 'G8', price: 3000, color: 'White' }

Here we have created a constructor and later we added an object such as color. Now doing console, it is clear new object is reflecting for samsung as well as for nokia. But the problem is we are here repeating code which looks much similar.

Do we have any other solution for it. Yes!, by prototype.

var Mobile = function (model_no) {
  this.model = model_no;
  this.price = 3000;
};

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('G8');

Mobile.prototype.color = 'white';
console.log(samsung);
console.log(nokia);

Output:

js-prototype-nokia-samsung

Instance member and Prototype member:

When you are writing properties simply by using key and value pairs then it's called instance member.

But when you are writing propories by using a prototype then it's called prototype member.

Secondly, instance members are visible on console but prototype members does not visible on console.

var Mobile = function (model_no) {
  this.model = model_no;
  this.price = 3000;
};

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('G8');

Mobile.prototype.color = 'white';
console.log(samsung.color);
console.log(nokia);

//output - white
//output - Mobile { model: 'G8', price: 3000 }

💡 TIP: The simple meaning of prototype - it's a parent class or super class or base case.


Iterate Instance and Prototype member using for...in loop:

var Mobile = function (model_no) {
  //instance member
  this.model = model_no;
  this.price = 3000;
};

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('G8');
//prototype member

Mobile.prototype.color = 'white';
console.log(Object.keys(samsung));
//it tell us in our object how many properties present

//output - [ 'model', 'price' ]

Here you are able to see only instance members, not prototype members.

Remember if you are using Object.keys and trying to iterate for your object then those object which is related to its only visible. i.e only instance members not prototype members.

If you want to see prototype members too then you need to use for..in loop.

var Mobile = function (model_no) {
  //instance member
  this.model = model_no;
  this.price = 3000;
};

var samsung = new Mobile('Galaxy');
var nokia = new Mobile('G8');
//prototype member

Mobile.prototype.color = 'white';

for (var key in samsung) {
  console.log(key);
}

//output - model, price, color

Prototype Object

In JavaScript we achieve inheritance by using a prototype.

💡 TIP: Every object is associated with another object in JavaScript and its root object is associated with null.

Prototype Inheritance

In JavaScript constructor does not inherit, its prototype inherits only.

//Super class
var Mobile = function () {
  this.a = 10;
};

Mobile.prototype.z = 30;

//sub class

var samsung = function () {
  Mobile.call(this);
  this.b = 20;
};

var s = new samsung();
console.log(s.a);

//output - 10

Here it is calling its parent constructor and initializing it so that we are able to access it.

//Super class
var Mobile = function () {
  this.a = 10;
};

Mobile.prototype.z = 30;

//sub class

var samsung = function () {
  Mobile.call(this);
  this.b = 20;
};

//Prototype inheritance

samsung.prototype = Object.create(Mobile.prototype);
samsung.prototype.constructor = samsung;

var s = new samsung();
console.log(s.a);
console.log(s.b);
console.log(s.z);

//output - 10, 20, 30

↥ back to top

JavaScript this

The JavaScript this keyword refers to the object it belongs to.

// Create an object
var person = {
  firstName: 'Sunil',
  lastName: 'Pradhan',
  id: 5566,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  },
};

// Display data from the object
console.log(person.fullName());

//output - Sunil Pradhan

In this example, this represents the person object because the person object "owns" the fullName method.

It has different values depending on where it is used:

  • In a method, this refers to the owner 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(), and apply() can refer this to any object.

this in a Method:

In an object method, this refers to the "owner" of the method.

// Create an object
var person = {
  firstName: 'Sunil',
  lastName: 'Pradhan',
  id: 5566,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  },
};

// Display data from the object
console.log(person.fullName());

//output - Sunil Pradhan

The person object is the owner of the fullName method.

this Alone:

When used alone, the owner is the Global object, so this refers to the Global object.

In a browser window the Global object is [object Window]:

var x = this;
alert(x);

//output - [object Window]

In this example, this refers to the window Object.

In strict mode, when used alone, this also refers to the Global object [object Window]:

'use strict';
var x = this;
alert(x);

//output - [object Window]

In this example, this refers to the window Object.

this in a Function (Default)

In a JavaScript function, the owner of the function is the default binding for this. So, in a function, this refers to the Global object [object Window].

function myFunction() {
  return this;
}
alert(myFunction());

//output - [object Window]

In this example, this represents the object that "owns" myFunction.

this in a Function (Strict):

JavaScript strict mode does not allow default binding. So, when used in a function, in strict mode, this is undefined.

'use strict';
function myFunction() {
  return this;
}
alert(myFunction());

//output  undefined

In a function, by default, this refers to the Global object. In strict mode, this is undefined, because strict mode does not allow default binding.

this in Event Handlers:

In HTML event handlers, this refers to the HTML element that received the event:

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

Object Method Binding:

In these examples, this is the person object (The person object is the "owner" of the function):

// Create an object
var person = {
  firstName: 'Sunil',
  lastName: 'Pradhan',
  id: 5566,
  myFunction: function () {
    return this;
  },
};

// Display data from the object
console.log(person.myFunction());

//output -

/*{
  firstName: 'Sunil', 
  lastName: 'Pradhan',
  id: 5566,
  myFunction: [Function: myFunction]
}*/

Here this represents the person object that "owns" the myFunction method.

// Create an object
var person = {
  firstName: 'Sunil',
  lastName: 'Pradhan',
  id: 5566,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  },
};

// Display data from the object
console.log(person.fullName());

//output - Sunil Pradhan

Here this represents the person object, because the person object "owns" the fullName method. In other words: this.firstName means the firstName property of this (person) object.

Explicit Function Binding:

The call() and apply() methods are predefined JavaScript methods. They can both be used to call an object method with another object as argument.

In the example below, when calling person1.fullName with person2 as argument, this will refer to person2, even if it is a method of person1:

var person1 = {
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  },
};
var person2 = {
  firstName: 'Sunil',
  lastName: 'Pradhan',
};

console.log(person1.fullName.call(person2)); // Will return "Sunil Pradhan"

//output - Sunil Pradhan

Here this refers to person2, even if it is a method of person1.

References

↥ back to top

Composition or Mixins

Let you create functions for humans which can eat, walk and talk. Again we want to extend it to Animal and Robot. All are ok, but robots can not eat whereas animals can eat, walk and talk but robots only walk and talk. Here we can not inherit all properties from human to Robot.

Because the eat() method will be a waste for us. To avoid this we can use Mixins.

With mixins you are allowed to attach a particular method() to your program.

//mixin

var eating = {
  eat: function () {
    return 'I can eat';
  },
};

var walking = {
  walk: function () {
    return 'I can walk';
  },
};

var talking = {
  talk: function () {
    return 'I can talk';
  },
};

var Rahul = Object.assign({}, eating, walking, talking);

//Object.assign = mixins

console.log(Rahul.eat());
console.log(Rahul.walk());
console.log(Rahul.talk());

//output - I can eat
//output - I can walk
//output - I can talk

Let now you want to create a Robot;

//mixin

var eating = {
  eat: function () {
    return 'I can eat';
  },
};

var walking = {
  walk: function () {
    return 'I can walk';
  },
};

var talking = {
  talk: function () {
    return 'I can talk';
  },
};

var Rahul = Object.assign({}, eating, walking, talking);

var RoboCop = Object.assign({}, walking, talking);

//Object.assign = mixins

console.log(Rahul.eat());
console.log(Rahul.walk());
console.log(Rahul.talk());

//output - I can eat
//output - I can walk
//output - I can talk

console.log(RoboCop.walk());
console.log(RoboCop.talk());

//output - I can walk
//output - I can talk

In future let you want to add a new feature to your robot which can start, then you will follow in such a way:

//mixin

var eating = {
  eat: function () {
    return 'I can eat';
  },
};

var walking = {
  walk: function () {
    return 'I can walk';
  },
};

var talking = {
  talk: function () {
    return 'I can talk';
  },
};

var starting = {
  start: function () {
    return 'RoboCop Start';
  },
};

var Rahul = Object.assign({}, eating, walking, talking);

var RoboCop = Object.assign({}, starting, walking, talking);

//Object.assign = mixins

console.log(Rahul.eat());
console.log(Rahul.walk());
console.log(Rahul.talk());

//output - I can eat
//output - I can walk
//output - I can talk

console.log(RoboCop.walk());
console.log(RoboCop.talk());
console.log(RoboCop.start());

//output - I can walk
//output - I can talk
//output - RoboCop Start

↥ back to top

JavaScript Class

JavaScript classes, introduced in ES6, Classes are in fact “Special functions”.

There are two way to define class in JavaScript:

  • Class Declaration
  • Class Expression

Class Declaration

Syntax:

class class_name {
  constructor() {
    Properties;
  }
  Methods;
}

The constructor method is a special method for creating and initializing an object created within a class. There can be only one special method with the name “constructor” in a class.

Example:

//Class declaration

class Mobile {
  constructor() {
    //Instance member
    this.a = 12;
    this.show = function () {
      return 'Instance member';
    };
  }

  //prototype memeber
  display() {
    return 'Prototype member';
  }
}

//need to create an object

var samsung = new Mobile();
console.log(samsung.a);
console.log(samsung.show());
console.log(samsung.display());

//output - 12
//output - Instance member
//output - Prototype member

Default Constructor:

If you do not specify a constructor method a default constructor is used.

//class declaration

class Mobile {
  display() {
    return 'Prototype memeber';
  }
}
var samsung = new Mobile();
console.log(samsung.display());

//output - Prototype memeber

Parameterized Constructor:

The constructor which has a parameter is called a parameterized constructor.

//class declaration

class Mobile {
  constructor(model_no) {
    this.model = model_no;
  }
  show() {
    return this.model + 'Price - 3000';
  }
}
var samsung = new Mobile('Galaxy');
console.log(samsung.show());

//output - GalaxyPrice - 3000

Class Expression

Class expressions can be named or unnamed.

Syntax(Unnamed):

var Mobile = class {
  constructor() {
    Properties;
  }
};

Example:

//unnamed

var Mobile = class {
  constructor(model_no) {
    this.model = model_no;
  }
  show() {
    return this.model + 'Price - 3000';
  }
};

var samsung = new Mobile('Galaxy');
console.log(samsung.show());

//output - GalaxyPrice - 3000

Syntax(Named):

var Mobile = class Mobile2 {
  constructor() {
    Properties;
  }
};

Example:

//named

var Mobile = class Mobile2 {
  constructor(model_no) {
    this.model = model_no;
  }
  show() {
    return this.model + 'Price - 3000';
  }
};

var samsung = new Mobile('Galaxy');
console.log(samsung.show());

//output - GalaxyPrice - 3000

Both are the same.

Class Hoisting in JavaScript:

Class declarations and Class expression are not hoisted. You first need to declare your class and then access it.

Class Inheritance:

Through prototype you can achieve inheritance but it's more complicated. ES6 makes it more easy through class inheritance.

The extends keyword is used in class declarations or class expressions to create a class which is a child of another class.

The extends keyword can be used to subclass, custom classes as well as built-in objects.

Example:

class Father {
  showFMoney() {
    return 'Father Money';
  }
}

class Son extends Father {
  showSMoney() {
    return 'Son Money';
  }
}

var s = new Son();
console.log(s.showFMoney());

//output - Father Money

💡 Note:

Base class/Super Class/Parent Class - all are same

Child class/Derived class/sub class - all are same

Super Method:

Super() is used to initialize the parent class constructor. If there is a constructor present in subclass, it needs to first call super() before using this.

💡 TIP: Derive class duty is to initialize the super class constructor before using it.

A constructor can use the super keyword to call the constructor of a parent class.

class Father {
  constructor(money) {
    this.Fmoney = money;
  }
  showFmoney() {
    return this.Fmoney + ' Father Money';
  }
}

class Son extends Father {
  constructor(money) {
    super(money);
  }
  showSMoney() {
    return 'Son Money';
  }
}

var s = new Son(1000);
console.log(s.showFmoney());
console.log(s.showSMoney());

//output - 1000 Father Money
//output - Son Money

Method Overriding

Same function name with different implementation.

class Father {
  show() {
    return 'Super Class';
  }
}

class Son extends Father {
  show() {
    return 'Sub Class';

    //redefined
  }
}
var s = new Son();
console.log(s.show());

//output - Sub Class

Static Method

The static keyword is used to define a static method for a class. static methods are called without creating objects and can’t be called through a class instance (Object).

Static methods are often used to create utility functions for an application.

💡 Note:

  • static method is related to full class, remember it is not related to object.It depends on class not on specific Object.
  • When we create function methods, it is for objects not for class.
class Mobile {
  static disp() {
    return 'Static method';
  }
}
//Mobile.disp();
console.log(Mobile.disp());

//output - Static method

↥ back to top

Variable Hoisting

Hoisting is JavaScript's default behavior of moving declarations to the top of the function, if defined in a function, or the top of the global context, if outside a function.

It means if you have declared a variable inside a function then its declaration part will move to the top.

But if you have not declared a variable inside any function simply declare it in your program then it globally moves to the top.

var a; //variable declaration
a = 10; //variable initialization

Example:

We write code

var a = 10;
document.write(a);
var b = 20;

JavaScript understand internally this way at compile phase

var a;
var b;
a = 10;
document.write(a);
b = 20;

💡 In summary first declaration and then initialization.

This is the reason why we are able to use variables in JavaScript even before it has been declared. But remember, only variable declarations are hoisted to the top, not variable initialization.

But due to this nature of hosting you can come across into problem;

Example(Variable):

var a = 10;
console.log(a + ' ' + b);
var b = 20;

//output 10 undefined

Why are you getting undefined?

Because JavaScript read your code:

var a;
var b;

a = 10;
console.log(a  +   +b);
b = 20;

b has been declared but later initialized. So that once console statment displayed then it reaches to b= 20 which result into undefined.

Example(Function):

We write code

var i = 'Hello';
console.log(i);

function show() {
  console.log(i);
}
show();

//output - Hello
//output - Hello

JavaScript understand internally this way at compile phase

var i;
i = 'Hello';
console.log(i);
function show() {
  console.log(i);
}

Lets create a new variable inside the function:

var i = 'Hello';
console.log(i);

function show() {
  console.log(i);
  var i = 'Sunil';
}
show();

//output - Hello
//output - undefined

JavaScript understand internally this way at compile phase

var i;
i = 'Hello';
console.log(i);
function show() {
  var i;
  console.log(i);
  i = 'Sunil';
}

Here variable declaration takes top of the function so that we are getting value of undefined.

Fix:

var i = 'Hello';
console.log(i);

function show() {
  var i = 'Sunil';
  console.log(i);
}
show();

//output - Hello
//output - Sunil

↥ back to top

Rest & Spread Operator

Rest operator

The Rest operator allows you to represent an indefinite number of arguments as an array.

Syntax:

function function_name(...args) {
  //code block
}

You can also pass some sample parameters while declaring Rest operator(...).

Syntax:

function function_name(a, ...args) {
  //code block
}

💡 TIP: The Rest operator(...) must be the last parameter to a function.

Example(Without parameter):

function show(...args) {
  console.log(args);
}

show(10, 20, 30, 40);

//output [ 10, 20, 30, 40 ]

Example(With parameter):

function show(a, ...args) {
  console.log(a);
  console.log(args);
}

show(10, 20, 30, 40);

output; //10
output; //[ 20, 30, 40 ]

Here you can see it assigns a = 10 and the rest of the arguments are assigned to 20, 30, 40.

This is the reason why it's called a Rest operator. Rest arguments for Rest parameters(...).

If you want to access only 20 or 30 then how can you do it?

Rest operator is just an array so by using index value you can access the value 20 or 30 it.

Example(Using index value):

function show(a, ...args) {
  console.log(a);
  console.log(args[1]);
}

show(10, 20, 30, 40);

//output 10
//output 30

Difference between Rest operator and Arguments object:

Arguments object is not a real Array, while Rest operator are Array instances, meaning methods like sort, map, forEach or pop can be applied on it directly.


↥ back to top

Spread operator

Spread operator is kind of the opposite of the Rest operator so while the Rest operator takes a variable as number of parameters or arguments and puts them into a single array.

The spread operator takes an array and splits it into the individual elements so Rest is to combine whereas spread is to split.

Syntax:

...stu;

Rest operator you will see mostly in functions whereas spread operator works in array and object.

Example(array):

//array
var a = [10, 20, 30];
var b = a;
console.log(a);
console.log(b);

//output - [ 10, 20, 30 ]
//output - [ 10, 20, 30 ]

Change in a code slighlty;

//array
var a = [10, 20, 30];
var b = a;
a[0] = 50;
console.log(a);
console.log(b);

//output - [ 50, 20, 30 ]
//output - [ 50, 20, 30 ]

You can see both values have been changed to 50. But why?

In Javascript array values never copy, it copies only references on the index.

//array
var a = [10, 20, 30];
var b = a;
a[0] = 50;
console.log(a[0]);
console.log(b[0]);

//output - 50
//output - 50

To remove this issue you can use the spread operator.

var a = [10, 20, 30];
var b = [...a]; //var b = [10, 20, 30]
a[0] = 50;
console.log(a[0]);
console.log(b[0]);

//output - 50
//output - 10

After using the spread operator you can see the changes.

//array
var a = [10, 20, 30];
var b = [...a]; //var b = [10, 20, 30]
a[0] = 50;
b[0] = 80;
console.log(a[0]);
console.log(b[0]);

//output - 50
//output - 80

Try with few more values;

//array
var a = [10, 20, 30];
var b = [...a, 40, 50];
console.log(a);
console.log(b);

//output - [ 10, 20, 30 ]
//output - [ 10, 20, 30, 40, 50 ]

Example:

//array
var a = [10, 20, 30];
var b = [5, ...a, 40, 50];
console.log(a);
console.log(b);

//output - [ 10, 20, 30 ]
//output - [ 5, 10, 20, 30, 40, 50 ]

Example:

//array
var a = [10, 20, 30];
var b = [40, 50, 60];
var c = [...a, ...b];
console.log(a);
console.log(b);
console.log(c);

//output - [ 10, 20, 30 ]
//output - [ 40, 50, 60 ]
//output - [ 10, 20, 30, 40, 50, 60 ]

Array creates reference but by using spread operators you will not face any issue of reference which creates an array.

Example(object):

//Object

var a = {
  courseName: 'JavaScript',
  tutor: 'Sunil',
};

var b = a;
console.log(a);
console.log(b);

//output - { courseName: 'JavaScript', tutor: 'Sunil' }
//output - { courseName: 'JavaScript', tutor: 'Sunil' }

Object is also a reference type.

//Object

var a = {
  courseName: 'JavaScript',
  tutor: 'Sunil',
};

var b = a;
a.courseName = 'React';
console.log(a);
console.log(b);

//output - { courseName: 'React', tutor: 'Sunil' }
//output - { courseName: 'React', tutor: 'Sunil' }

The value of b has also changed. We can use here the spread operator.

//Object

var a = {
  courseName: 'JavaScript',
  tutor: 'Sunil',
};

var b = { ...a };
a.courseName = 'React';
console.log(a);
console.log(b);

//output - { courseName: 'React', tutor: 'Sunil' }
//output - { courseName: 'JavaScript', tutor: 'Sunil' }

Here the value a has only change not b.

If you want to add something.

//Object

var a = {
  courseName: 'JavaScript',
  tutor: 'Sunil',
};

var b = { ...a, duration: 'TwoMonths' };
a.courseName = 'React';
console.log(a);
console.log(b);

//output - { courseName: 'React', tutor: 'Sunil' }
//output - { courseName: 'JavaScript', tutor: 'Sunil', duration: 'TwoMonths' }

Try to merge it;

//Object

var a = {
  courseName: 'JavaScript',
  tutor: 'Sunil',
};

var b = { duration: 'TwoMonths' };
var c = { ...a, ...b };

console.log(c);

//output - { courseName: 'JavaScript', tutor: 'Sunil', duration: 'TwoMonths' }

Here reference are not being copied rather value copy.


↥ back to top

Module - Import & Export

What are JavaScript Module?

If you go through any book you will notice that the author divides the book into chapters and sections, but why?

Because this makes it possible for a reader to understand the progression in the book and to easily find a specific part that they are interested in, also the author is able to clearly indicate what the focus is on.

Now just like how a book is divided into chapters; JavaScript Module divide a program into sections of code that by some criteria belong together.

The benefit of organizing a program into modules is that it helps people who aren't yet familiar with the code to find what they are looking for.

In short: Module is a JavaScript file where we write codes. The objects in a module are not available for use, unless the module file exports them.

In ES6 the Module syntax has been standardized. So let's say we have two files ModuleA.js and ModuleB.js then each of these files become a JavaScript Module.

So if we have a function in ModuleB.js to use it in ModuleA.js we export from ModuleB.js and import in ModuleA.js.

js-module

And that's the basic idea behind JavaScript Module - Export and Import

Module Setup

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>JavaScript Module</title>
    <script type="module" src="ModuleA.js"></script>
  </head>
  <body>
    <h1>Learn JavaScript Module</h1>
  </body>
</html>

Two more files: ModuleA.js, ModuleB.js


↥ back to top

Exporting Module

export - The export statement is used when creating JavaScript modules to export functions, objects, or primitive values from the module so they can be used by other programs with the import statement.

There are two different types of export - named and default. You can have multiple named exports per module but only one default export.

Named Exports

You can have multiple named exports per module. Named exports are useful to export several values. During the import, it is mandatory to use the same name of the corresponding object.

We have two files ModuleA.js & ModuleB.js, now let's head over to ModuleB.js and create a new variable.

ModuleB.js

let fname = 'Sunil';

Now let's say we want to export this variable fname so that it can be used in other modules. So for that we just need to use the export keyword. So add export at the beginning of the statement.

ModuleB.js

export let fname = 'Sunil';

So now our variable fname is ready to be accessed in other modules.

So how do we import that over to ModuleA.js?

So to import variables we use the keyword import followed by name of the variable, type fname within curly braces.

But from where are we importing it? From a file called ModuleB.js in the current directory(./)

ModuleA.js

import { fname } from './ModuleB.js';

Try log to the console fname:

import { fname } from './ModuleB.js';
console.log(fname);

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>JavaScript Module</title>
    <script type="module" src="ModuleA.js"></script>
  </head>
  <body>
    <h1>Learn JavaScript Module</h1>
  </body>
</html>

Let's save all files and head over to the browser to see console of index.html. There you go - Sunil.

js-named-exports

So we have created a variable fname equals Sunil in ModuleB.js and importing it into ModuleA.js, and we have displayed it on the log of index.html.

But how do JavaScript modules communicate with each other?

Let’s create one more variable in ModuleB.js:

ModuleB.js

export let fname = 'Sunil';
export let lname = 'Pradhan';

Now to import this we can just specify with the comma the name of the variable so lname over here:

ModuleA.js

import { fname, lname } from './ModuleB.js';
console.log(fname);

In console log use backticks for fname and lname.

ModuleA.js

import { fname, lname } from './ModuleB.js';
console.log(`${fname} ${lname}`);

Output:

js-named-exports-two

Now let's say we have 10 variables to export, in such a case this export keyword can be replaced from every sentence and we can just have one export.

ModuleB.js

let fname = 'Sunil';
let lname = 'Pradhan';

export { fname, lname };

So if we had 10 variables we just would specify all 10 variables separated by a comma. So now when we export it and import it, everything else remains the same.

ModuleA.js

import { fname, lname } from './ModuleB.js';
console.log(`${fname} ${lname}`);

Output:

js-named-exports-two

Sunil Pradhan, so nothing changed.

So that's another way to export your variables. You can either do it in the same line or you can have a single export at the end specifying the list of variables.

The next point about importing is that we can specify an alias.

ModuleA.js

import { fname as f, lname as l } from './ModuleB.js';
console.log(`${fname} ${lname}`);

So when you use an alias for an import you must use that alias else it would throw an error, so we need to change this to f and l.

ModuleA.js

import { fname as f, lname as l } from './ModuleB.js';
console.log(`${f} ${l}`);

Output:

js-named-exports-two

💡 TIP: JavaScript Module imports are hoisted and read-only.

That means whenever you have an import statement it is always going to be hoisted to the top and more fname and lname can be imported but can never be changed but what you can change is the properties of objects.

ModuleB.js

let fname = 'Sunil';
let lname = 'Pradhan';

let obj = {
  name: 'Rula',
};

export { fname, lname, obj };

ModuleA.js

import { fname, lname, obj } from './ModuleB.js';
obj.name = 'Anil';
console.log(obj.name);
console.log(`${fname} ${lname}`);

So let's save this and the name has been changed from Rula to Anil.

js-named-exports-three

Default Exports

Whenever we have modules that export only a single value or a function then, we can make use of the default keyword while exporting.

💡 TIP: You can have only one default export per module and it can be imported with any name.

So consider this example, in our ModuleB.js, I am going to have a new variable:

ModuleB.js

let fname = 'Sunil';

export default fname;

And now since this is going to be the only export from this particular file or module we can use export default and then without curly braces the name of the variable.

While importing it there are few changes the first thing is you can leave out the curly braces so we don't have to use the curly braces while importing default export.

And the second thing is unlike named export where the name of the variable while exporting has to match the name while importing in module but in default export and import the name doesn't have to match.

So over here we can just call it firstName :

ModuleA.js

import firstName from './ModuleB.js';

console.log(firstName);

This is going to work because we are going to be exporting only a single value from ModuleB.js and that is going to be captured in whatever we are importing.

So firstName is going to be mapped onto fname, so if we go ahead and log to the console our output would be same i.e Sunil.

js-named-exports

So that's how default export work. Another thing to keep in mind as we can also provide alias for importing default but the only thing is we need to use curly braces.

So default as f, so this default is going to be the default import from ModuleB.js and we just going to alias it with f.

ModuleA.js

import { default as f } from './ModuleB.js';

console.log(f);

So when we save this and refresh we will get the same output.

js-named-exports

So aliases work with default imports as well.


↥ back to top

Exporting Functions and Classes

As we exported variables we can also export functions and classes in ES6.

Let's take an example:

Over here in ModuleB.js we are going to create a new function greet and this is going to accept a parameter and all it does is going to log to the console.

ModuleB.js

function greet(message) {
  console.log(message);
}

Then to export the function just like exporting a variable we can attach export keyword at the beginning.

ModuleB.js

export function greet(message) {
  console.log(message);
}

So our function is ready to be exported, let's go ahead and import it in ModuleA.js.

Within curly braces the name of the function so greet and where are we importing it from the current directory i.e ModuleB.js, so now that we have the function we can go ahead and call it.

ModuleA.js

import { greet } from './ModuleB.js';

greet('Hello Sunil');

let's pass Hello Sunil. So when we save this our output would be:

js-function-module-export-import

So that's the basic idea behind exporting functions and importing them. Just add the export keyword and you import it and you can call it in the module where you have imported it.

So next let's have a look at how to export and import classes.

For this we are going to create a new class GreetMessage and this is going to have a constructor and within the constructor,let's just log "Constructor."

And let's also have a simple function greet and it's just going to log to the console "Greet Function."

ModuleB.js

export function greet(message) {
  console.log(message);
}

class GreetMessage {
  constructor() {
    console.log('Constructor');
  }
  greet() {
    console.log('Greet Function');
  }
}

Now to export the class we can use the export keyword again and attach it at the very beginning.

ModuleB.js

export function greet(message) {
  console.log(message);
}

export class GreetMessage {
  constructor() {
    console.log('Constructor');
  }
  greet() {
    console.log('Greet Function');
  }
}

So let's go back to ModuleA.js and by next to greet we need to specify GreetMessage.

And over here let's create a new instance of the class, so let gm is equal to a new GreetMessage and then call gm.greet().

ModuleA.js

import { greet, GreetMessage } from './ModuleB.js';

greet('Hello Sunil');

let gm = new GreetMessage();
gm.greet();

And when we save this and head over to the browser our output would be:

js-class-module-export-import

So we have Hello Sunil which is the function and then we have the constructor invoked and then we have the greet function log to the console.

Here we have the constructor and the greet function both of them were imported and invoked when we created this instance of the class.


↥ back to top

Summary - Module - Import & Export

Importing defaults:

You can have only one default export per module. A default export can be imported with any name.

js-importing-defaults

Importing named:

You can have multiple named exports per module. Named exports are useful to export several values. During the import, it is mandatory to use the same name of the corresponding object.

js-importing-named

Named export and import for variable:

Mobile.js

//Named export variable

export const a = 10;

App.js

//Named import variable
import { a } from './mobile.js';
console.log(a);

Same but different way to represent:

Mobile.js

//Named export variable

const a = 10;
export { a };

Named export function:

Mobile.js

//Named export function

export function show() {
  console.log('Hello Sunil');
}

App.js

//Named import function
import { show } from './mobile.js';
show();

Same but different way to represent:

Mobile.js

//Named export function

function show() {
  console.log('Hello Sunil');
}

export { show };

Named export class:

Mobile.js

//Named export class

export class Nokia {
  volumeup() {
    console.log('High Volume');
  }
}

App.js

//Named import class
import { Nokia } from './mobile.js';
const n = new Nokia();
n.volumeup();

Same but different way to represent:

Mobile.js

//Named export class

class Nokia {
  volumeup() {
    console.log('High Volume');
  }
}

export { Nokia };

App.js

//Named import class
import { Nokia } from './mobile.js';
const n = new Nokia();
n.volumeup();

Multiple named export:

Mobile.js

//Multiple Named export

class Nokia {
  volumnUp() {
    console.log('High Volume');
  }
}

function show() {
  console.log('Hello Module');
}

export const a = 10;

export { Nokia, show };

App.js

//Multiple Named import
import { Nokia, show, a } from './mobile.js';
const n = new Nokia();
n.volumnUp();
show();
console.log(a);

Importing all:

Mobile.js

//Multiple Named export

class Nokia {
  volumnUp() {
    console.log('High Volume');
  }
}

function show() {
  console.log('Hello Module');
}

export const a = 10;

export { Nokia, show };

App.js

//Multiple Named import
import * as device from './mobile.js';
const n = new Nokia();
n.volumnUp();
show();
console.log(a);

Use default and named together:

Mobile.js

//default and named export

class Nokia {
  volumnUp() {
    console.log('High Volume');
  }
}

function show() {
  console.log('Hello Module');
}

export const a = 10;
export default Nokia;
export { show };

App.js

// Named import
import Nokia, { show, a } from './mobile.js';
const n = new Nokia();
n.volumnUp();
show();
console.log(a);

Default import and export for variable:

Mobile.js

//Default export variable

const a = 10;
export default a;

App.js

//Default import variable
import a from './mobile.js';
console.log(a);

Function import and export:

Mobile.js

//Default export function

export default function show() {
  console.log('Hello Module');
}

App.js

//Default import function
import show from './mobile.js';
show();

Same but different way to represent:

Mobile.js

//Default export function

function show() {
  console.log('Hello Module');
}

export default show;

Class import and export:

Mobile.js

//Default export class

export default class Nokia {
  volumnUp() {
    console.log('High Volume');
  }
}

App.js

//Default import class
import Nokia from './mobile.js';

const n = new Nokia();
n.volumnUp();

Same but different way to represent:

Mobile.js

//Default export class

class Nokia {
  volumnUp() {
    console.log('High Volume');
  }
}

export default Nokia;

↥ back to top

Destructuring - Array & Object

Destructuring is a convenient way of extracting multiple values from data stored in objects and Arrays.

Array Destructuring:

Create a simple employee array and is going to hold three values first one is Sunil, which is first name then we will have Pradhan which is the last name and then we will have Male which is the gender.

let employee = ['Sunil', 'Pradhan', 'Male'];

Next within square brackets we are going to say fname as first name, lname which is last name and then gender and this is going to be assigned to this employee array.

let [fname, lname, gender] = employee;

So what looks like an array creation is actually the destructuring of this employee array.

So the first three elements of the employee array are assigned to these three variables so Sunil gets assigned fname, Pradhan to lname and Male to gender.

Here we are destructuring this employee array by splitting up this individual elements and assigning them to these variables.

let employee = ['Sunil', 'Pradhan', 'Male'];
let [fname, lname, gender] = employee;

console.log(fname);
console.log(lname);
console.log(gender);

//output

//Sunil
//Pradhan
//Male

So that's a basic idea in array destructuring. We take the individual elements from an array and assign it to individual variables.

Now let's consider the second example, this time we don't have this male gender anymore.

let employee = ['Sunil', 'Pradhan'];
let [fname, lname, gender] = employee;

console.log(fname);
console.log(lname);
console.log(gender);

//output

//Sunil
//Pradhan
//undefined

So we can still specify any number of variables on the left hand side while destructuring an array but once the mapping is done in this case Sunil to first name Pradhan to last name and we don't have any more values to assign to the variable so undefined is going to be the value for this gender and so on.

We can also omit variables on the left hand side, that means:

let employee = ['Sunil', 'Pradhan', 'Male'];
let [fname, lname, gender] = employee;

console.log(fname);
console.log(lname);
console.log(gender);

//output

//Sunil
//Pradhan
//Male

Here in this case we only want to save this male into this gender variable, we don't want to unnecessarily have memory for a first name and last name since we are not going to be using it.

In such a scenario we can just omit it but this comma right here is essential.

let employee = ['Sunil', 'Pradhan', 'Male'];
let [, , gender] = employee;

console.log(gender);

//output - Male

We can also destructure using the Rest operator which helps us to have a single variable that can contain a group of elements;

let employee = ['Sunil', 'Pradhan', 'Male'];
let [fname, ...elements] = employee;

console.log(fname);
console.log(elements);

//output

//Sunil
//[ 'Pradhan', 'Male' ]

So we have Sunil which is assigned to first name and now since we have a Rest operator the remaining values are getting stored into an array and assigned to this element.

We can also use destructuring with default values;

let employee = ['Sunil', 'Pradhan'];

let [fname, lname, gender] = employee;

console.log(fname);
console.log(lname);
console.log(gender);

//Output - Sunil, Pradhan, undefined

We don't have the gender anymore here so can specify a default value;

let employee = ['Sunil', 'Pradhan'];

let [fname, lname, gender = 'Male'] = employee;

console.log(fname);
console.log(lname);
console.log(gender);

//Output - Sunil, Pradhan, Male

We have Sunil being a Male since we are not specifying Male or a third value in our employee array. There is no destructuring for this gender variable so it is going to take Male as a default value and it's going to log on to the console.


↥ back to top

Object Destructuring:

Let employee there's going to be an object first name is going to be Sunil and then we'll have a last name which is going to be Pradhan and they will have gender which is going to be Male.

let employee = {
  fname: 'Sunil',
  lname: 'Pradhan',
  gender: 'Male',
};

Now destructure this employee object we need to use curly braces {}. We need to specify the variable names and we have to ensure that the property name is the same as this variable name.

So we need to have fname, lname, gender and this is going to be equal to an employee.

let employee = {
  fname: 'Sunil',
  lname: 'Pradhan',
  gender: 'Male',
};

let { fname, lname, gender } = employee;

console.log(fname);
console.log(lname);
console.log(gender);

//output - Sunil, Pradhan, Male

So we have destructure this employee object by taking these individual property values and assigning them to the variables.

Now let's say our property name is huge and so we don't want to use such a variable name throughout in our code. So in such a case we can create an alias.

let employee = {
  fname: 'Sunil',
  lname: 'Pradhan',
  gender: 'Male',
};

let { fname: f, lname: l, gender: g } = employee;

console.log(f);
console.log(l);
console.log(g);

//output - Sunil, Pradhan, Male

So that's pretty much how destructure works in JavaScript objects.

You have an object and then you use the curly braces and assign it to the object and each property name should match the variable name and then the value will get assigned to it.


↥ back to top

JavaScript Symbols

The purpose of a symbol is to generate a unique ID but the funny thing is that we never get access to that ID.

let s = Symbol();
console.log(typeof s);

//output - symbol

We can also pass an optional symbol description while creating a symbol. So within parentheses we can specify a string so we can just call this first symbol.

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

//output- symbol
//output - Symbol(First Symbol)

So when we call the toString() method on the symbol we get the description. Okay so now let's create two more symbols.

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol();
let s3 = Symbol();

console.log(s2 === s3);

//output- symbol
//output - Symbol(First Symbol)
//false

Therefore a symbol always creates a unique ID.

Now let's pass a description 'Test';

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol('Test');
let s3 = Symbol('Test');

console.log(s2 === s3);

//output- symbol
//output - Symbol(First Symbol)
//false

It's still false. So it doesn't matter what the description is, a symbol is always going to create a unique ID.

Now let's say that we have created a new symbol but we need to get hold of that symbol so that we can use the same symbol again in a different or the same file. So for that purpose we have a built in symbol registry.

So to add a symbol to the registry we use the symbol.for() method.

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol('Test');
let s3 = Symbol('Test');

console.log(s2 === s3);

let s4 = Symbol.for('RegSymbol');

Here's the thing though Symbol.for doesn't add the symbol right away it checks if a symbol with the key RegSymbol already exists in the registry if it does it will return that symbol over here to s4.

If it doesn't exist then it will create a new symbol in the registry.

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol('Test');
let s3 = Symbol('Test');

console.log(s2 === s3);

let s4 = Symbol.for('RegSymbol');
let s5 = Symbol.for('RegSymbol');
console.log(s4 === s5);

//output - symbol
//output - Symbol(First Symbol)
//output - false
//output - true

There you go it's true so what happened here is that when we did a Symbol.for on the first time a new symbol was created in the global registry with this description.

And when Symbol.for was called again with the same description this symbol was retrieved and stored in s5 file so.

Now s4 and s5 both the symbols are the same we have no clue as to what the ID for these two symbols are but we just know that they are equal.

Now let's say we want the key that was associated with the symbol when the symbol was added to the global registry. So for that we have another method called Symbol.keyFor.

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol('Test');
let s3 = Symbol('Test');

console.log(s2 === s3);

let s4 = Symbol.for('RegSymbol');
let s5 = Symbol.for('RegSymbol');
console.log(s4 === s5);
console.log(Symbol.keyFor(s4));

//output - symbol
//output - Symbol(First Symbol)
//output - false
//output - true
//output - RegSymbol

Here Symbol.keyFor is going to give us a key for a symbol.

So when we come across a symbol and we are not sure what it is used for we can use this method to get the description. Now you know that this symbol was actually used to set up a symbol in the global registry.

Okay now that we know symbol is used to create a unique ID a good place to use them or use symbols is in object properties.

So we can have a new symbol let fname = Symbol() and then we can create a new object that person is equal to and by using the bracket notation we can use the symbol over here [fname] as the property.

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol('Test');
let s3 = Symbol('Test');

console.log(s2 === s3);

let s4 = Symbol.for('RegSymbol');
let s5 = Symbol.for('RegSymbol');
console.log(s4 === s5);
console.log(Symbol.keyFor(s4));

let fname = Symbol();
let person = {
  [fname]: 'Sunil',
};
console.log(Object.getOwnPropertyNames(person));

//output - symbol
//output - Symbol(First Symbol)
//output - false
//output - true
//output - RegSymbol
//output - []

Now we have created a unique property inside this object so we never have to worry about our code conflicting with existing methods or being accidentally overwritten. Because this property is always going to be unique.

So now when we try to log the console Object.getOwnPropertyNames(person), we don't get this property first name listed out because it is in fact a symbol, so we need to use another static method which is now present in ES6, namely getOwnPropertySymbols.

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol('Test');
let s3 = Symbol('Test');

console.log(s2 === s3);

let s4 = Symbol.for('RegSymbol');
let s5 = Symbol.for('RegSymbol');
console.log(s4 === s5);
console.log(Symbol.keyFor(s4));

let fname = Symbol();
let person = {
  [fname]: 'Sunil',
};
console.log(Object.getOwnPropertyNames(person));
console.log(Object.getOwnPropertySymbols(person));

//output - symbol
//output - Symbol(First Symbol)
//output - false
//output - true
//output - RegSymbol
//output - []
//output - [ Symbol() ]

And if we pass, let's say FirstName

let s = Symbol('First Symbol');
console.log(typeof s);
console.log(s.toString());

let s2 = Symbol('Test');
let s3 = Symbol('Test');

console.log(s2 === s3);

let s4 = Symbol.for('RegSymbol');
let s5 = Symbol.for('RegSymbol');
console.log(s4 === s5);
console.log(Symbol.keyFor(s4));

let fname = Symbol('FirstName');
let person = {
  [fname]: 'Sunil',
};
console.log(Object.getOwnPropertyNames(person));
console.log(Object.getOwnPropertySymbols(person));

//output - symbol
//output - Symbol(First Symbol)
//output - false
//output - true
//output - RegSymbol
//output - []
//output - [ Symbol(FirstName) ]

So this is the new static method in ES6 which we can use to list the symbols used for an object.


↥ back to top

Symbol iterator:

As we know ES6 provides a new way to iterate over objects and that is the for...of loop but the for...of loop can be used with all types of objects. For an object to work with the for...of loop it needs to have a special method and the special method is called as the iterator method.

But how do we know if the object has an iterator method? By checking to see if the object has a method defined for the key Symbol.iterator so this is where this well-known Symbol.iterator comes into action.

What we are doing here is checking to see if a method exists for the object at this particular key so at Symbol.iterator if typeof string of symbols iterator returns a method or a function then this object can be used with the for...of loop.

Now let's have a look which of these types can be used with the for...of loop.

let str = 'Hello';
let arr = [1, 2, 3];
let num = 5;
let obj = { name: 'Sunil' };

console.log('For string -' + typeof str[Symbol.iterator]);
console.log('For array -' + typeof arr[Symbol.iterator]);
console.log('For number -' + typeof num[Symbol.iterator]);
console.log('For object -' + typeof obj[Symbol.iterator]);

//output - For string - function
//output - For array - function
//output - For number -undefined
//output - For object -undefined

So for string it's a function that means we can use a string in a for...of loop, for array we can use a for...of loop because the type of the method is function or the type of method add similar iterator is a function.

But for number and object it is undefined so that means to say that we cannot use the for...of loop with number and object.

Now that is the main use of Symbol.iterator to check a for...of loop can be used with a particular object or not.

Now does that mean that objects are not iterable well ? no!

We can write our own special iterator method, so that even an object can be used with the for...of loop.


↥ back to top

Iterables and Iterators:

ES6 introduces iteration which is a new way to traverse data and iteration revolves around two key concepts namely iterables and iterators.

Now an iterable is any object that implements a method whose key is Symbol.iterator so we will have an iterable which is nothing but an object, which has a property Symbol.iterator method and this method is going to return an iterator.

Iterable {
  [Symbol.iterator()]: iterator
}

What is an iterator? An iterator is an object that is going to implement a next method. So it is going to have a next method and this next method knows how to access elements in a collection, be it an array or a string or maps or sets.

Iterable {
  [Symbol.iterator()]: Iterator
}

Iterator{
  next():
}

And its returns an object, let's call this iterator IResultObj and this iterator IResultObj is nothing but an object that contains two properties.

So let us copy this and the first property is a value property and this can be of any data type so this value is going to be the actual value within the collection.

And the second property is a boolean flag called done, so this done indicates if the iteration is complete or not complete.

So if done is true the iteration is complete.

Iterable {
  [Symbol.iterator()]: Iterator
}

Iterator{
  next(): IResultObj
}

IResultObj{
  value: any
  done: bool
}

If it is false then there are more elements to be iterated over.

As we already mentioned in ES6 array, strings, maps and sets are all iterables but to understand better about iterators let's create our own iterator that works with arrays.

Let's go over here and let's create a new array and call this iterable then create our iterator, now it's going to be a function and let's name it createIterator and this is going to accept an array and let's have a count variable that we used to iterate or keep track of each element within the array.

let iterable = [1, 2, 3];

function createIterator(array) {
  let count = 0;
  return {
    next: function () {
      return count < array.length?
      {value: array[count++], done:false};
    },
  };
}

And if you see over here an iterator this contains a next method so it's going to return something and that is a next method so this next is going to be a function. And it's going to return this result object.

Now there are two conditions while returning this object.

If the count of the array or the current count is less than array.length then we are going to return the value is going to be an array of count, but we also need to move on to the next element so count++ and done is going to be false.

So the count is less than array.length which means to say that we have more elements that need to be iterated. We are not yet done with the iteration and if the count is equal to or greater than array.length that means we have hit the end of our iteration. So we are going to be returning value undefined and done true.

Now let us create let myIterator and assign it to the function so createIterator and pass the iterable array.

We have a reference to this function and by making use of the next method we can iterate through each of these elements.

let iterable = [1, 2, 3];

function createIterator(array) {
  let count = 0;
  return {
    next: function () {
      return count < array.length
        ? { value: array[count++], done: false }
        : { value: undefined, done: true };
    },
  };
}

let myIterator = createIterator(iterable);
console.log(myIterator.next());

//output - { value: 1, done: false }

We are getting an object value is one and done as false so the first element. If we repeat this two more times;

let iterable = [1, 2, 3];

function createIterator(array) {
  let count = 0;
  return {
    next: function () {
      return count < array.length
        ? { value: array[count++], done: false }
        : { value: undefined, done: true };
    },
  };
}

let myIterator = createIterator(iterable);
console.log(myIterator.next());
console.log(myIterator.next());
console.log(myIterator.next());

//output - { value: 1, done: false }
//output - { value: 2, done: false }
//output - { value: 3, done: false }

And we get value two three and we are not yet done with the iteration and finally when we call this again;

let iterable = [1, 2, 3];

function createIterator(array) {
  let count = 0;
  return {
    next: function () {
      return count < array.length
        ? { value: array[count++], done: false }
        : { value: undefined, done: true };
    },
  };
}

let myIterator = createIterator(iterable);
console.log(myIterator.next());
console.log(myIterator.next());
console.log(myIterator.next());
console.log(myIterator.next());

//output - { value: 1, done: false }
//output - { value: 2, done: false }
//output - { value: 3, done: false }
//output - { value: undefined, done: true }

We get value undefined and we are done with the iteration. This functionality in fact is what the for...of loop uses it internally calls the next method until this done is true.

So until the iteration is completed it keeps calling this next method and that is how it iterates through the elements of a collection.


↥ back to top

Iterating Objects:

If we have an object say person with the first name and last name as the properties and when we try to use a for...ofloop;

let person = {
  fname: 'Sunil',
  lname: 'Pradhan',
};

for (let p of person) {
  console.log(p);

//output - TypeError: person is not iterable

So the for...of loop doesn't work with objects by default.

let person = {
  fname: 'Sunil',
  lname: 'Pradhan',
};

for (let p of person) {
  console.log(p);
}

person[Symbol.iterator] = function () {
  let properties = Object.keys(person);
  let count = 0;
  let isDone = false;
  let next = () => {
    if (count >= properties.length) {
      isDone = true;
    }
    return { done: isDone, value: this[properties[countK++]] };
  };
  return { next };
};

//output - TypeError: person is not iterable

So we start off by defining a function at the key Symbol.iterator for this person object so our first line is going to be a person of Symbol.iterator is equal to a function.

And this function we start off by declaring three variables that we are going to be making use of in this next method.

So initially we are going to have the properties equal to object keys and pass this person object. So properties is going to contain first name and lastname.

And then we have a count variable initialized to zero to keep track of the count and we also have isDone variable which is going to be boolean and set to false and that is going to indicate if the iteration is complete or not.

At the key Symbol.iterator implements a next function which returns an object so what this next function is going to do is if the count is greater than the number of property for the person object it is going to say isDone equals true, which means that the iteration is complete.

And then we are going to return done is going to be the same as isDone variable, it's going to be the true or false and the value is going to be for this object the property add count or the value at this particular property so the property the value at first name and value at last name.

let person = {
  fname: 'Sunil',
  lname: 'Pradhan',
};

person[Symbol.iterator] = function () {
  let properties = Object.keys(person);
  let count = 0;
  let isDone = false;
  let next = () => {
    if (count >= properties.length) {
      isDone = true;
    }
    return { done: isDone, value: this[properties[count++]] };
  };
  return { next };
};

for (let p of person) {
  console.log(p);
}

//output - Sunil
//output - Pradhan

That is how you use objects with the for...of loop, you need to define your own method at Symbol.iterator key.


↥ back to top

Generators

We know about function that once they start executing it will always run to completion before any other code can run, however ES6 generator is a special type of function which can be paused in the middle of execution run some other code and then resume the same function from where we left off.

And this pausing of execution is possible with the help of a new keyword known as the yield keyword.

So let's understand this with an example now the syntax of a generator is very much alike a function so we just have the function keyword but the only differences after the function keyword we have an asterisk.

Syntax:

function *

So function asterisk and then name of the function, so let's have create generator as the name and this is going to you make use of this yield keyword.

function* createGenerator() {
  yield 1;
  console.log('After 1st yield');
  yield 2;
}

After first yield and then we are also going to have yield two. So what we are basically doing here is that in this generator first we are going to yield the value one and then the execution is going to pause and the generator is going to resume its execution when we again tell it to continue its execution.

Then it's going to execute these two lines of code, so console.log as well as yield two. So basically with every execution it is going to hit the next yield point.

This is going to be the point where this function is going to pause.So now we can create a reference to this generator.

function* createGenerator() {
  yield 1;
  console.log('After 1st yield');
  yield 2;
}

let myGen = createGenerator();

Let myGen= createGenerator(), and this is going to provide an reference and it's not going to start executing this function.

Now to invoke this function or start execute we need to call the next method on the generator so myGen.next().

function* createGenerator() {
  yield 1;
  console.log('After 1st yield');
  yield 2;
}

let myGen = createGenerator();
console.log(myGen.next());

//output - { value: 1, done: false }

We are provided with an object the value is one and done this boolean flag set default and this is very much like what we saw with iterators.

So over here the only difference is that done will be set to false when it reaches the last yield statement or there are no more yield statements in this generator.

So we can call this again so let's call it twice and more.

function* createGenerator() {
  yield 1;
  console.log('After 1st yield');
  yield 2;
}

let myGen = createGenerator();
console.log(myGen.next());
console.log(myGen.next());
console.log(myGen.next());

//output - { value: 1, done: false }
//output - After 1st yield
//output - { value: 2, done: false }
//output - { value: undefined, done: true }

So object value one done false so that was called after this first next method and the execution was paused.

And then these two lines were executed for the next method so we have after first yield an object value - done false.

And finally when we call this next method again it identifies that there are no more yield statements and hence done is set to true and the value is undefined.

So only when there are no more yields done is set to true and the value is undefined so basically generator is a special function capable of pausing and resuming execution with the help of this yield keyword.

Now if you look here a generator returns an object that provides the same next method that is expected by a for...of loop. So generators can be used to simplify our code when we write our custom iterators.

let person = {
  fname: 'Chandler',
  lname: 'Bing',
};

person[Symbol.iterator] = function () {
  let properties = Object.keys(person);
  let count = 0;
  let isDone = false;
  let next = () => {
    if (count >= properties.length) {
      isDone = true;
    }
    return { done: isDone, value: this[properties[count++]] };
  };
  return { next };
};

for (let p of person) {
  console.log(p);
}

To iterate over a simple object and instead of having to write so much of code we can use a generator to simplify this and we can replace it.

let person = {
  fname: 'Sunil',
  lname: 'Pradhan',
};

person[Symbol.iterator] = function* () {
  let properties = Object.keys(person);
  for (let t of properties) {
    yield this[t];
  }
};

for (let p of person) {
  console.log(p);
}

//ouput - Sunil
//output - Pradhan

So over here the person Symbol.iterator remains the same and we obtained all the properties but from then on so count is done an implementation of the next method all that is handled by this generator so we replaced function by just a function as tricks and properties remains the same.

And now since we have a collection of properties we can use a for..of loop let t of properties and then yield is going to be made use of.

So this is going to yield each key and we are going to be making use of the value at each key. So this is basically yield first name and yield last name.

This is one really useful feature of generator to be made use when we write our custom iterators.


↥ back to top

Sets & Maps

JavaScript Sets

A set is nothing but a list of values but this list cannot contain any duplicates. Unlike arrays where we access the individual elements in sets we just check if a value is present or not we don't really access the value.

💡 TIP: A set is a data structure which contains a list of values that are unique.

So to create a new set we need to follow the following pattern:

let mySet = new Set();

Now once we have a new set we can add elements to the set by calling the add() method on the set.

Now to check the size of the set or how many elements are present in the set we use the size property.

let mySet = new Set();
mySet.add('Hello');
console.log(mySet.size);

//output - 1

The values we store in a set are not restricted to string values so we can have also a numeric value.

let mySet = new Set();

mySet.add('Hello');
mySet.add(1);
console.log(mySet.size);

//output - 2

Let's try to add the same value again;

let mySet = new Set();

mySet.add('Hello');
mySet.add(1);
mySet.add(1);
console.log(mySet.size);

//output - 2

Its size still remains 2. So a set can only contain unique values that means when you try to insert or add a duplicate value it is going to ignore that particular value.

Now let's create two new objects.

let mySet = new Set();
let ob1 = {};
let ob2 = {};

mySet.add('Hello');
mySet.add(1);

console.log(mySet.size);

But when we try to add mySet.add(ob1) and mySet.add(ob2) we get the result of 4.

let mySet = new Set();
let ob1 = {};
let ob2 = {};

mySet.add('Hello');
mySet.add(1);

mySet.add(ob1);
mySet.add(ob2);
console.log(mySet.size);

//output - 4

Here we are getting the result 4 because objects are not converted to strings the two objects will be unique.

We can also initialize values using an array during the creation of a set.

let mySet = new Set();
let ob1 = {};
let ob2 = {};

mySet.add('Hello');
mySet.add(1);

mySet.add(ob1);
mySet.add(ob2);
console.log(mySet.size);

let newSet = new Set([1, 2, 3, 4, 4, 4]);
console.log(mySet.size);

//output - 4
//output - 4

The first four values were unique and were saved into new set but the last two values were duplicate values and were ignored. So that is how the size of new set is 4.

You can also change the add method to add elements to a set so we can have:

let mySet = new Set();
let ob1 = {};
let ob2 = {};

mySet.add('Hello');
mySet.add(1);

mySet.add(ob1);
mySet.add(ob2);
console.log(mySet.size);

let newSet = new Set([1, 2, 3, 4, 4, 4]);
console.log(mySet.size);

let chainSet = new Set().add('Hello').add('World');
console.log(chainSet.size);

//output - 4
//output - 4
//output - 2

So when we log to the console chainSet.size should have two.

To check for existence of a value in a set we use the has method. So we are here a newSet, let's see if the value 1 is present or not.

let mySet = new Set();
let ob1 = {};
let ob2 = {};

mySet.add('Hello');
mySet.add(1);

mySet.add(ob1);
mySet.add(ob2);
console.log(mySet.size);

let newSet = new Set([1, 2, 3, 4, 4, 4]);
console.log(mySet.size);

let chainSet = new Set().add('Hello').add('World');
console.log(chainSet.size);
console.log(newSet.has(1));

//output - 4
//output - 4
//output - 2
//output - true

As we use has method to check for an existence of a value similarly to delete a value from a set we use the delete method. So let's delete the value 1.

Initially it was 4 now we are deleting an element so the new size should be 3.

let mySet = new Set();
let ob1 = {};
let ob2 = {};

mySet.add('Hello');
mySet.add(1);

mySet.add(ob1);
mySet.add(ob2);
console.log(mySet.size);

let newSet = new Set([1, 2, 3, 4, 4, 4]);
console.log(mySet.size);

let chainSet = new Set().add('Hello').add('World');
console.log(chainSet.size);
console.log(newSet.delete(1));
console.log(newSet.size);

//output - 4
//output - 4
//output - 2
//output - true
//output - 3

In a nutshell, we create a set using new and then we can add using add method. We can check for an existence using the has method and delete using the delete method and the size of the set can be found out using the size property.

WeakSets

On the last section you saw the set type but it can also be called as a strong set because of the way in which it stores object references.

So let's try to understand with an example. Let's first create a new set.

let mySet = new Set();

We are also going to have an object so let key is equal to a pair of curly braces and let's try to add that.

let mySet = new Set();
let key = {};
mySet.add(key);

console.log(mySet.size);

//output - 1

Now we are going to set key is equal to null and then log the size again.

let mySet = new Set();

let key = {};
mySet.add(key);
console.log(mySet.size);

key = null;
console.log(mySet.size);

//output - 1
//output - 1

So what we can conclude from the above example is that even though the key was set to null.

A reference to the key object still existed in our set and we can just as easily retrieve it by saying key is equal to the spread operator on mySet and we can have of 0.

let mySet = new Set();

let key = {};
mySet.add(key);
console.log(mySet.size);

key = null;
console.log(mySet.size);

key = [...mySet][0];

//output - 1
//output - 1

This is going to give us that object back. And what sometimes to aid with garbage collection and avoid memory leaks we would prefer that the reference in a set to disappear when all other references disappear.

And for this purpose ES6 introduced, WeakSets. A weak set is very much like a strong set.

It has the add, has, delete method but two main differences are it can store only object references and not primitive values and the object references are weak.

So if all other references are removed then a WeakSets allows for garbage collection.

Now to create a WeakSets;

let set = new WeakSet();
let key = {};
set.add(key);
console.log(set.has(key));

//output - true

So key is a value in this set, now when we have key is equal to null and when we run this code the reference to key in the WeakSets is no longer accessible.

let set = new WeakSet();
let key = {};
set.add(key);
console.log(set.has(key));
key = null;

//output - true

And the funny thing here is, it is not even possible to verify if the reference is removed because we need at least one reference to this object to pass in the has method.

So we just have to put our faith in the JavaScript engine.

The only advantage of WeakSets over a strong set is memory is handled properly with WeakSets.

So let's say if we have to only track the references the object and nothing more than that then a WeakSets should be preferred over a strong set.

JavaScript Maps

A map is nothing more than a collection of key value pairs.

Unlike sets where we check if a value exists or not, with maps we actually want to retrieve the value.

In maps both the key and the value can be of any type unlike objects where the type of the property is always a string.

To create a new map;

let myMap = new Map();

To add an item we use the set method, so myMap.set and within parentheses we specify the key value pair.

let myMap = new Map();

myMap.set('fname', 'Sunil');

We can also have numeric values too;

let myMap = new Map();

myMap.set('fname', 'Sunil');
myMap.set('age', 18);

To retrieve a value we need to use the get method.

let myMap = new Map();

myMap.set('fname', 'Sunil');
myMap.set('age', 18);

console.log(myMap.get('fname'));
console.log(myMap.get('age'));

//output - Sunil
//output - 18

We can also use objects as keys within a map;

let myMap = new Map();

myMap.set('fname', 'Sunil');
myMap.set('age', 18);

console.log(myMap.get('fname'));
console.log(myMap.get('age'));

let ob1 = {};
let ob2 = {};

myMap.set(ob1, 10);
myMap.set(ob2, 20);

console.log(myMap.get(ob1));
console.log(myMap.get(ob2));

//output - Sunil
//output - 18

//output - 10
//output - 20

We can also use the size property to know how many key value pairs are present in a particular map.

let myMap = new Map();

myMap.set('fname', 'Sunil');
myMap.set('age', 18);

console.log(myMap.get('fname'));
console.log(myMap.get('age'));

let ob1 = {};
let ob2 = {};

myMap.set(ob1, 10);
myMap.set(ob2, 20);

console.log(myMap.get(ob1));
console.log(myMap.size);

//output - Sunil
//output - 18

//output - 10
//output - 4

We can also use the has method to check if a key exists in a map.

let myMap = new Map();

myMap.set('fname', 'Sunil');
myMap.set('age', 18);

console.log(myMap.get('fname'));
console.log(myMap.get('age'));

let ob1 = {};
let ob2 = {};

myMap.set(ob1, 10);
myMap.set(ob2, 20);

console.log(myMap.get(ob1));
console.log(myMap.size);
console.log(myMap.has('fname'));

//output - Sunil
//output - 18

//output - 10
//output - 4
//output - true

It returns true so if it did not exist it was going to return false.

Now we can also have a delete method to remove a key value pair.

let myMap = new Map();

myMap.set('fname', 'Sunil');
myMap.set('age', 18);

console.log(myMap.get('fname'));
console.log(myMap.get('age'));

let ob1 = {};
let ob2 = {};

myMap.set(ob1, 10);
myMap.set(ob2, 20);

console.log(myMap.get(ob1));
myMap.delete('fname');

console.log(myMap.size);
console.log(myMap.has('fname'));

//output - Sunil
//output - 18

//output - 10
//output - 3
//output - false

So the number of elements or key value pairs was reduced by one and we don't have fname in the map anymore.

For this it has returned false and finally we have a clear method that removes all the key value pairs from a map.

let myMap = new Map();

myMap.set('fname', 'Sunil');
myMap.set('age', 18);

console.log(myMap.get('fname'));
console.log(myMap.get('age'));

let ob1 = {};
let ob2 = {};

myMap.set(ob1, 10);
myMap.set(ob2, 20);

console.log(myMap.get(ob1));
myMap.delete('fname');
myMap.clear();

console.log(myMap.size);
console.log(myMap.has('fname'));

//output - Sunil
//output - 18

//output - 10
//output - 0
//output - false

Iterating over Maps

There is another way to add key value pairs to a map and that is by using arrays doing map initialization.

So we can have let myMap is equal to new Map but this time within parentheses we can specify an array. As a result this array is going to contain more arrays in turn.

let myMap = new Map([
  ['fname', 'Sunil'],
  ['lname', 'Pradhan'],
]);

Now that we have a new map. Let's see now how to iterate over this map.

If we need to iterate only the keys of the map then we make use of map keys method in a for..of statement.

let myMap = new Map([
  ['fname', 'Sunil'],
  ['lname', 'Pradhan'],
]);

for (let key of myMap.keys()) {
  console.log(key);
}

//output - fname
//output - lname

These are just the keys and similarly if we need only the values then we make use of my map dot values.

let myMap = new Map([
  ['fname', 'Sunil'],
  ['lname', 'Pradhan'],
]);

for (let value of myMap.values()) {
  console.log(value);
}

for (let key of myMap.keys()) {
  console.log(key);
}

// output - Sunil
// output - Pradhan

// output - fname
// output - lname

But if you need both the key and value then we make use of myMap.entries().

So for we can have let and entry of my map dot entries and in console dot log let's make use of backticks.

let myMap = new Map([
  ['fname', 'Sunil'],
  ['lname', 'Pradhan'],
]);

for (let entry of myMap.entries()) {
  console.log(`${entry[0]} -> ${entry[1]}`);
}

//output - fname -> Sunil
//output - lname -> Pradhan

We can also make use of destructuring for the same cause;

let myMap = new Map([
  ['fname', 'Sunil'],
  ['lname', 'Pradhan'],
]);

for (let [key, value] of myMap.entries()) {
  console.log(`${key} -> ${value}`);
}

//output - fname -> Sunil
//output - lname -> Pradhan

WeakMaps

In WeakMaps the keys can only be object and the object references are weak, meaning they don't interfere with the garbage collection.

Now to create a WeakMaps we say;

let myMap = new WeakMap();

We can also have an object that we are going to be using as a key and then we can add this key value pair.

let myMap = new WeakMap();
let ob1 = {};
myMap.set(ob1, 'Hello World');
console.log(myMap.get(ob1));

//ouput - Hello World

Now let us add ob1 is equal to null, at this point the WeakMap is empty and there is no way really to verify this.

let myMap = new WeakMap();
let ob1 = {};
myMap.set(ob1, 'Hello World');
console.log(myMap.get(ob1));
ob1 = null;

//ouput - Hello World

↥ back to top

Map method

By Map method we can quickly iterate over an array and return a new array with the desired changes applied.

Definition: The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

Example:

const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map((x) => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]

Here we have an array of numbers then we call the map method on the array.

The map method accepts a function as an argument and of course what you see here is an arrow function. There is one parameter called "x" and in the function body we return x multiply by 2.

The entire operation is then assigned to a variable called map1 which is then log to the console.

If we run this code you get the expected output i.e[2, 8, 18, 32].

So what the map method does is go over each element in the array and apply a transformation specified in the function body.

In our example we have an array of four numbers so the transformation function is executed once for each of the four numbers.

On first execution the parameter "x" will contain a value of 1 it is transformed to 1 multiplied by 2 which is 2, which you can see here in the output.

Second execution we have "x" is equal to 4 which is transformed to 4 into 2 which is 8 and similarly 9 into 2 which is 18 and 16 into 2 which is 32.

So we have a list of numbers and we are able to return a list of numbers after applying some transformation using the map method.

Reference

↥ back to top

JavaScript Promises

A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved (e.g., a network error occurred).

A promise may be in one of 3 possible states: fulfilled, rejected, or pending.

How Promises work

It will be in one of 3 possible states:

  • Fulfilled
  • Rejected
  • Pending

A promise is settled if it’s not pending (it has been resolved or rejected). Sometimes people use resolved and settled to mean the same thing: not pending.

Once settled, a promise can not be resettled. The immutability of a settled promise is an important feature.

Example:

function func1() {
  return new Promise(function (resolve, reject) {
    setTimeout(() => {
      const error = true;
      if (!error) {
        console.log('Function: Your promise has been resolved');
        resolve();
      } else {
        console.log('Function: Your promise has not been resolved');
        reject('Sorry not fulfilled');
      }
    }, 2000);
  });
}
func1()
  .then(function () {
    console.log('Sunil!! - Thanks for resolving');
  })
  .catch(function (error) {
    console.log('Sunil!! - Very bad bro. Reason: ' + error);
  });

//output:

//Function: Your promise has not been resolved
//Sunil!! - Very bad bro. Reason: Sorry not fulfilled

JavaScript Promises are better substitute of callback funtion.

References

↥ back to top

JavaScript Async/Await

Async and Await are extensions of promises.

Async

Async functions enable us to write promise based code as if it were synchronous, but without blocking the execution thread. It operates asynchronously via the event-loop.

Async functions will always return a value. Using async simply implies that a promise will be returned, and if a promise is not returned, JavaScript automatically wraps it in a resolved promise with its value.

Example:

async function firstAsync() {
  return 27;
}

firstAsync().then(alert); // 27

Running the above code gives the alert output as 27, it means that a promise was returned, otherwise the .then() method simply would not be possible.

Await

The await operator is used to wait for a Promise. It can be used inside an Async block only. The keyword Await makes JavaScript wait until the promise returns a result.

It has to be noted that it only makes the async function block wait and not the whole program execution.

The code block below shows the use of Async Await together.

Example:

async function firstAsync() {
  let promise = new Promise((res, rej) => {
    setTimeout(() => res("Now it's done!"), 1000);
  });

  // wait until the promise returns us a value
  let result = await promise;

  // "Now it's done!"
  alert(result);
}
firstAsync();
References

↥ back to top

Object Oriented Programming - OOP

Object oriented programming (OOP) is a programming language model organized around objects rather than “actions” and data rather than logic.

Four pillar of OOPS: Encapsulation, abstraction, inheritance,polymorphism

Encapsulation:

It encapsulates your data.

Abstraction:

Which is important only to show that much and rest needs to hide it.

Inheritance:

Inheritance means something you receive from your ancestry.

Polymorphism:

polymorphism means you are writing a single function() but it works differently for different situations.


↥ back to top


Complementary Resources

When you struggle to understand a concept, I suggest you look for answers on the following resources: