Skip to content

Latest commit

 

History

History

javascript

JavaScript Language

Variables

Environment: Collection of bindings and their values that exist at a given time is called the environment

Primitive Types

There are 7 primitive types in JavaScript.

  1. null
  2. undefined
  3. number
  4. bigint (ES10)
  5. string
  6. boolean
  7. symbol
const num = 100n;
typof num // bigint

const num2 = BigInt(100);
typeof num2 // bigint

const id1 = Symbol('id1');
typeof id1 // symbol

Some fundamentals:

var number1 = 200 // number: integer
let number2 = 300.50 // number: floating-point
const name = "Aladin" // string
const boolean = true // true | false
const nothing = null // absent of object
const undef = undefined // absent of value

// const means constant. It can not be modifed once defined

console.log(number1, typeof number1)
console.log(number2, typeof number2)
console.log(name, typeof name)
console.log(boolean, typeof boolean)
console.log(nothing, typeof nothing)
console.log(undef, typeof undef)

// var exist in function scope
{
  var str = "Hello World";
  console.log(str);
}
console.log(str); // Okay no error

console.log();
// let and const is in block scope
{
  let localStr1 = "Life is Cool";
  const localStr2 = "Nothing is impossible";

  console.log(localStr1);
  console.log(localStr2);
}

//console.log(localStr1); // ReferenceError: localStr1 is not defined
//console.log(localStr2); // ReferenceError: localStr2 is not defined

Absent of Value

/**
 * null vs undefined
 * you can use any to describe absent of value
 */

const absent1 = null;
const absent2 = undefined;
console.log(absent1 == absent2); // true
console.log(absent1 === absent2); // value and identity check false

console.log();
/**
 * Special Numbers
 */
const sp1 = Infinity
const sp2 = -Infinity
const sp3 = NaN // Not a number
console.log(sp1, typeof sp1)
console.log(sp2, typeof sp2)
console.log(sp3, typeof sp3)
console.log((0/0)) // output: Nan

Operators

// Unary Operator
let uVal = 10
console.log(-uVal)

++uVal; // --uVal => pre-increment, pre-decrement
console.log(uVal) // 11

uVal++; // uVal-- => post-increment, post-decrement
console.log(uVal) // 12

// Difference between ++uVal and uVal++
uVal = 100
console.log(++uVal)
console.log(uVal)
console.log(uVal++)
console.log(uVal)

// Binary Operator
let bNum1 = 20
let bNum2 = 40
let resultBN = bNum1 + bNum2 // bNum1 - bNum2
console.log(`${bNum1}+${bNum2}=${bNum1 + bNum2}`)

resultBN = resultBN + 10
console.log(resultBN)
resultBN += 1 // ++resultBN or resultBN++
console.log(resultBN)

console.log()
resultBN = 100
console.log(resultBN)
resultBN = resultBN - 10
console.log(resultBN)
resultBN = resultBN * 2
console.log(resultBN)
resultBN = resultBN / 7
console.log(resultBN) // 25.714285714285715
console.log(Math.floor(resultBN)) // 25

// Remainder operator
let x = 10
let y = 3
console.log(x % y)

// Exponential function
let aNum = 2
console.log("Exponential: " + Math.pow(aNum, 8))

Number Methods

// Number to string
let num = 100
let sNum = num.toString()
console.log(typeof sNum) // string

// Fixed number of decimal
// toFixed() returns a string
let num = 99.9481
num.toFixed(0) // 100
num.toFixed(2) // 99.95
num.toFixed(8) // 90.9481000

// Variable to Numbers
// Number()
Number(true);          // returns 1
Number(false);         // returns 0
Number("100");         // returns 100
Number("  990");       // returns 990
Number(" 10  ");       // returns 10
Number("10.33");       // returns 10.33
Number("10,33");       // returns NaN
Number("XYZ");        // returns NaN

// String to Int
parseInt("10");         // returns 10
parseInt("10.33");      // returns 10
parseInt("10 20 30");   // returns 10
parseInt("10 years");   // returns 10
parseInt("years 10");   // returns NaN 

// String to Float
parseFloat("10");        // returns 10
parseFloat("10.33");     // returns 10.33
parseFloat("10 20 30");  // returns 10
parseFloat("10 years");  // returns 10
parseFloat("years 10");  // returns NaN

// Date to a Number
// Returns the number of milliseconds since 1.1.1970
Number(new Date('2019-12-19')) // 1576713600000

// Minimum and Maximum Number in JavaScript
let min = Number.MIN_VALUE // 5e-324
let max = Number.MAX_VALUE // 1.7976931348623157e+308

Statements Expression Comments

The smallest part of codes that javascript interpreter can execute is called statement

The combination of value, variable and operators are called expression

Comment

// Single line comment

/* This is a
multiline comment */

String

const strType1 = "Life is good" // double quotes
const strType2 = 'Let\'s do it' // single quotes
const strType3 = `Sum of 2+2=${2+2}` // template literal

// Template literal ${} inside value computed and converted to string

/**
 * Expression
 * In computer programming expression part of code that generates value
 */
console.log(2+2) // 2+2 is expression

const name = 'Mahmud'
const country = "Bangladesh"
const profession = 'Programmer'
const career = `Computer ${profession}` // String interpolation

// String concatenation
const name = 'Mahmud' + ' ' + 'Ahsan'
const name = 'Mahmud'.concat(' Ahsan')

// Accessing characters in String
const name = "Mark Zuckerberg"
name.charAt(0) 
name[0] 

// String Length
const str = 'hello'
str.length

// String Comparison
const name1 = "Mark Zuckerberg"
const name2 = "Bill Gates"

if (name1 < name2) {
  console.log(`${name1} is less than ${name2}`)
}
else if (name1 > name2) {
  console.log(`${name1} is greater than ${name2}`)
}
else {
  console.log(`${name1} is equal to ${name2}`)
}

// Converting Case
const name = "Mark Zuckerberg"
name.toLowerCase()
name.toUpperCase()

// Matching
name.startsWith('Mark') // true
name.search('rk') // 2

name.indexOf('Z') // 5
name.lastIndexOf('r') //13 look for last occurrence 

// Slicing
name.slice(5) // Zuckerberg

// Substring
name.substring(0, 5) // Mark

// Replace
// It returns a new string and match only the first
console.log(name.replace('Mark', 'Mahmud')) // Mahmud Zuckerberg

// Replacing using Regular Expression
console.log(name.replace(/MARK/i, 'Mahmud'))

// String to Array
let str = 'Mahmud Ahsan'
let name = str.split(' ')
console.log(name) // [ 'Mahmud', 'Ahsan' ]

// Iterating string
let str = "Hello World";
for (let char of str){
    console.log(char);
}

Array

An ordered collection of items which is mutable. JavaScript array is a special type of object.

// Empty array
const array = []
const array = new Array() // it's bad practice


const array = [1, 2, 3]
const array = new Array(1, 2, 3)

// Array items accessed by index number
array[0] // accessing first item
array[array.length - 1] // accessing last item

// Modifying array
array[0] = 5

// Adding item in a array as the last item
array.push(10)
array[array.length] = 10

// Get the last item and remove from original array
array.pop()

// Get first item and remove from original array
array.shift()

// Adding item as the first element
array.unshift(100)

// Count items
array.length

// Deleting item from array
delete array[1] // but it just assign undefined at index 1

// Checking item existence
array.includes(item)

// Index of item
array.indexOf(item)

// Adding new items in an array
let array = [1, 2, 3, 4]
array.splice(4, 0, 5, 6, 7)
/*
The first parameter (4) defines the position where new elements should be added (spliced in).
The second parameter (0) defines how many elements should be removed.
The rest of the parameters (5, 6, 7) define the new elements to be added.
** The splice() method returns an array with the deleted items:
*/
array.forEach(item => console.log(item)) // 1 2 3 4 5 6 7

// Remove array elements using splice
let array = [1, 2, 3, 4]
array.splice(2, 1)
console.log(array) // [ 1, 2, 4 ]

// Merging Arrays
let arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]
let allArr = arr1.concat(arr2) // [ 1, 2, 3, 4, 5, 6 ]

// Array slicing
// slice() doesn't modify original array
let arr1 = [1, 2, 3, 4, 5, 6]
let arr2 = arr1.slice(1, 3)
console.log(arr2) // [ 2, 3 ]

// Reverse
array.reverse()

// Checking Array type
Array.isArray(array)

// Array items to String
let array = [1, 2, 3, 4]
let str = array.join('')
console.log(str) // 1234

// Max and Min number in an array
let array = [100, 25, 1, 5, 10]
Math.max.apply(null, array) // 100
Math.min.apply(null, array) // 1

Array Sorting

// Sorting
// sort() function short values as String
let array = ['banana', 'apple', 'pine-apple', 'guava']
array.sort() // [ 'apple', 'banana', 'guava', 'pine-apple' ]

// Sorting number should by done by providing function
let array = [100, 25, 1, 5, 10]
array.sort((a, b) => a - b) // asc for desc b-a
console.log(array) // [ 1, 5, 10, 25, 100 ] 

// Sorting object arrays
let people = [
    {name: 'ABC', age: 60},
    {name: 'XYZ', age: 25},
    {name: 'DEF', age: 50},
]

people.sort((a, b) => a.age - b.age)
console.log(people)
/* Output
[
  { name: 'XYZ', age: 25 },
  { name: 'DEF', age: 50 },
  { name: 'ABC', age: 60 }
]
*/

Array Iterations

// forEach method
// Accessing each item

let arr = [1, 2, 3, 4, 5]
arr.forEach(item => {
    console.log(item * 2)
})

Map

map() function creates a new array based on the function provided. It takes 3 arguments. value, index and the array You can omit index and array if you no need.

// Only even index number will be doubled

let arr = [1, 2, 3, 4, 5]
let evenSquare = arr.map((value, index, array) => {
  if (index % 2 == 0) {
    return value * 2
  } else {
    return value
  }
})
console.log(evenSquare)

Filter

Same like map() function, returns a new array with passing the filter.

// Odd Numbers
let arr = [1, 2, 3, 4, 5]
let odd = arr.filter(item => item % 2 != 0)
console.log(odd)

Reduce array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

To produce a single value from an array. reduce() function takes 4 arguments:

  • The total (the initial value / previously returned value)
  • The item value
  • The item index
  • The array itself
let arr = [1, 2, 3, 4, 5]
let sum = arr.reduce((total, item) => total + item)
console.log(sum) // 15

Some Other Methods

// every() method check all array values pass a test
let arr = [1, 2, 3, 4, 5]
arr.every(value => value > 0) // true

// some() method checks if some values pass a test
let arr = [-11, 2, 3, 4, 5]
arr.some(value => value > 0) // true

// indexOf() method returns the index of first occurrence
let arr = [-11, 2, 3, 4, 4, 5]
arr.indexOf(4) // 3

// lastIndexOf() method returns the index of last occurrence
let arr = [-11, 2, 3, 4, 4, 5]
arr.lastIndexOf(4) // 4

Set

Set object store unique values of any type
const sets = new Set([1, 2, 3, 4, 5]);

// Number of items
sets.size

// Adding item in a set
sets.add(6)

// Checking item existence
sets.has(5)

// Remove item
sets.delete(5)

// Remove all
sets.clear()

// Iteration 1
sets.forEach(item => {
    console.log(item);
})

// Iteration 2
for (let item of sets){
    console.log(item);
}

// Convert set to array
const arr = Array.from(sets)

Map

Object and Map is almost same with some difference. A Map object iterates its elements in insertion order — a for...of loop returns an array of [key, value] for each iteration. For more referencce: MDN Map

// an empty map
let myMap = new Map()

// adding element
// key can be integer or string type
myMap.set('foo', true) // key: value

// item exist check
myMap.has('foo') // true or false

// item delete
myMap.delete('foo')

Object

A regular JavaScript object.

const Person = {
    name: 'Ahsan',
    count: 'Bangladesh',
};

console.log(Person);
Shorthand property name in object

When object property name and initializing variable name are same we can use shorthand syntax

// ES5
var person = {
  name: name
};
console.log(person.name);

// ES6
const personSame = {
  name,
};
console.log(personSame.name);
Concise Method name in object
// ES5
var person = {
  name: 'Mahmud',
  getName: function(){
    return this.name;
  }
};

console.log(person.getName());

// ES6
const personAgain = {
  name: 'Mahmud Ahsan',
  getName(){
    return this.name;
  }
};

console.log(personAgain.getName());
Computed property name
const key = 'key' + 1;
const obj = {
  [key]: 'data',
};

console.log(obj[key]);
Some useful object methods
// geting keys as array using Object class method keys()
let obj = {
  name: 'mark',
  age: 35
};

let keys = Object.keys(obj); // ['name', 'age']

// Iterating object
for (let key in obj) {
  console.log(obj[key]);
}

Destructuring

Destructuring is an easier way to access properties in objects and arrays

Object destructuring

const person = {
  name: "Mahmud",
  country: "Bangladesh",
};

// individual variable
// const { name } = person;
// console.log(name);

// be careful to use actual property name
// here if i use nameAgain it will not work
// const { nameAgain, country } = person;
// console.log(nameAgain, " " + country);

// Correct Solution
const { name, country } = person;
console.log(name, " " + country);

// in function call common destructuring scenario
const personName = ( {name} ) => {
  console.log(name.toUpperCase());
};

personName(person);
Destructuring array. In this case use [] square brackets instead of {}
const arrNumbers = [1, 2, 3, 4, 5];

const [ one, two, three ] = arrNumbers;
console.log(one, two, three);

Spread Operator

Spread operator (...Name) allows an iterable to spread or expand individually inside a receiver. Iterables can be strings, arrays, sets, etc.
// arr1 and arr2 are same this is not the right way
const arr1 = [1, 2, 3, 4];
const arr2 = arr1;
console.log(arr1 === arr2);

arr2.push(5);
console.log(arr1);

// ...array return each element of an array
// here arr3 is completely new array and has no relation with arr1
const arr3 = [...arr1, 6];
console.log(arr3);
console.log(arr1 === arr3);
Spread operator for object is proposal feature but it works with babel transpiler
const obj1 = {
  name: 'rice',
  price: 20
};

const type = 'groceries';

const obj2 = {...obj1, type}
console.log(obj2);

Function

A regular function
function sum(items) {
    return items.reduce((total, item) => total + item );
}

console.log(sum([1, 2, 3]));
Function binding with a variable name
const sum = function(items) {
    return items.reduce((total, item) => total + item );
}

console.log(sum([1, 2, 3]));
Default value in function parameter
const personDetails = (name, country='Bangladesh') => {
  console.log(name + " " + country);
}

personDetails("mahmud");
personDetails('mark', 'Malaysia');

Regular function vs Function binding with variable

  • We can not call the function binded with a variable before defining the function.
  • The following will throw an error
callX(10);
const callX = function (x) {
    console.log(x);
}

Correct Solution

const callX = function (x) {
    console.log(x);
}
callX(10);

BUT we can call a regular function anywhere in the context

// It works perfectly fine
callX(10);
function callX (x) {
    console.log(x);
}

Arrow Function

An arrow function is shorter than a regular function expression

// Arrow function 1
const squareArrow1 = (n) => {
  return n * n;
};
console.log("Arrow1: " + squareArrow1(7));

// Arrow function 2
// When there is one parameter, () is optional
const squareArrow2 = n => {
  return n * n;
};
console.log("Arrow2: " + squareArrow1(9));

// Arrow function 3
// When no curly braces provided after arrow, that means implicit returns
const squareArrow3 = n => n * n;
console.log("Arrow3: " + squareArrow1(11));

// Invalid 
// Must have to pass () beside parameters before arrow 
//const addArrow = a, b => a + b; // ERROR

// Valid
const addArrow = (a, b) => a + b; 

// Empty parameter
// Must have to provid ()
const helloWorld = () => {
  console.log("Hello World");
}
helloWorld();

Class

JavaScript classes are syntactic sugar over existing prototype based inheritance.
constructor is a special method to initialize class object while initiating.
class Address {
  constructor(city, country){
    this.city = city;
    this.country = country;
  }

  print(){
    console.log(this.city);
    console.log(this.country);
  }
}

// initiating instance of class
const myAddress = new Address('dhaka', 'bangladesh');
myAddress.print();
static method can be called with the class name
class Point {
  constructor(x, y){
    this.x = x;
    this.y = y;
  }

  static distance(pointA, pointB){
    const ptX = Math.pow((pointB.x - pointA.x), 2);
    const ptY = Math.pow((pointB.y - pointA.y), 2);
    const dt  = Math.sqrt(ptX + ptY);
    return dt;
  }
}

const pt1 = new Point(5, 2);
const pt2 = new Point(10, 3);
const distanceOfPt = Point.distance(pt1, pt2);
console.log(distanceOfPt);
Subclass
class Car {
  constructor(brand, type){
    this.brand = brand;
    this.type = type;
  }

  print(){
    console.log('Brand: ' + this.brand);
    console.log('Type: ' + this.type);
  }
}

// if subclass has constructor it needs to call
// super before using this
class Honda extends Car {
  constructor(brand, type, model){
    super(brand, type);
    this.model = model;
  }

  print(){
    super.print();
    console.log('Model: ' + this.model);
  }
}

const honda = new Honda('honda', 'sedan', 'accord');
honda.print();

Promise

A promise object represents an eventual completion or failure for an asynchronous operation.
Promise has 3 states:
  1. Pending
  2. Fulfilled
  3. Rejected

When a pending promise either fulfilled or rejected and if a corresponding handler is attached by 'then' method, the handler will be called. If it is rejected, the corresponding catch method if attached will be called.

 const getData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(()=>{
      resolve('data received');
    }, 1000);

    // reject example 
    setTimeout(()=>{
      reject('network disconnected');
    }, 500);
  });
 };

 const dataFromServer = getData();
 
 dataFromServer.then(
    (value)=>{
      console.log(value);
    }, 
    (error)=>{ // implicit catch within then
      console.log(error);
    }
 ); 

  /*
  // explicit catch to detect rejection
   dataFromServer.then(
    (value)=>{
      console.log(value);
    })
    .catch((error)=>{
      console.log(error);
    }  
 );
 */

Async Await

async/await functions are built onto promise. A function starts with async keyword means, it will must return a promise either implicitly or explicitly.
The keyword await makes JavaScript wait until the promise settled and return the result

Example 1:

 const sum = async (a, b) => {
   return a + b;
 };
 console.log(sum); // [AsyncFunction: sum]
 console.log(sum(1, 2)); // Promise { 3 }
 const result = sum(100, 200);
 result.then(value => {
  console.log(value);
 });

Example 2:

const pow = async (num, pow) => {
  return new Promise((resolve, reject)=>{
    const r = Math.pow(num, pow);
    resolve(r);
  });
 };

 pow(2, 2).then(val => {console.log(val)});

Example 3:

 const getData = async () => {
    const data = new Promise((resolve, reject) => {
      setTimeout(()=>{
        resolve("data received");
      }, 2000);
    });

    console.log('test 1');
    let result = await data;
    console.log('test 2');
    return result;
 };

 getData().then(result => {
   console.log(result);
 });

Example 4:

async / await with synchronous fashion without using then of promise object

function task1() {
  console.log('Task 1');
}

function task2() {
  console.log('Task 2');
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('Task 2'), 2000);
  });
}

function task3(data) {
  console.log(`Task 3 with ${data}`);
}

async function main() {
  task1();
  const data = await task2();
  task3(data);
}

main();

We can also redefine the main() function like this. In this case we use then method of promise object for the asynchronous operation.

function main() {
  task1();
  task2().then(data => task3(data));
}