Java
Javascript

add method to object dynamically

function Person(firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

const member = new Person('Lydia', 'Hallie')
console.log(member.getFullName()) // will throw error

Person.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`
}
console.log(member.getFullName()) // will run fine now

(from question 11)https://github.com/lydiahallie/javascript-questions#11-whats-the-output

add method to object dynamically

function Person(firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

const member = new Person('Lydia', 'Hallie')
console.log(member.getFullName()) // will throw error

Person.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`
}
console.log(member.getFullName()) // will run fine now

(from question 11)https://github.com/lydiahallie/javascript-questions#11-whats-the-output

Array.prototype.map()

  • creates a new array
  • the function passed to map is run for each element
const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2); // [2, 8, 18, 32]

functional. requires a callback

Array.prototype.map()

  • creates a new array
  • the function passed to map is run for each element
const array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2); // [2, 8, 18, 32]

functional. requires a callback

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Arrayhttps://github.com/denysdovhan/wtfjs#true-is-false

array: append item to array in immutable manner

- Mutable:
  - to add: unshift, push
  - to remove: shift, pop
  - to remove from b/w: splice(startIndex, deleteCount)
- Immutable:
  - to add: concat
  - to remove: slice(start,end)
  - copy: spread

new array

  • Array.from({length:3},()=>0)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Arrayhttps://github.com/denysdovhan/wtfjs#true-is-false

array: append item to array in immutable manner

- Mutable:
  - to add: unshift, push
  - to remove: shift, pop
  - to remove from b/w: splice(startIndex, deleteCount)
- Immutable:
  - to add: concat
  - to remove: slice(start,end)
  - copy: spread

new array

  • Array.from({length:3},()=>0)

Arrow functions

  • syntactic sugar. removed need for
    • return keyword
    • function keyword
    • curly brackets

When not to use arrow function

Object Methods

const mario = {
    lives: 3,
    oneUp: () => {
        this.lives++; // this will not update lives
    }
}
  • Arrow function do not have their own this
  • this.lives will refer to outer environment

Object prototype

Dynamic context

  • arrow functions bind context statically. ie upon function declaration

When not to use arrow functionsQuestion that provoked this thought

Arrow functions

  • syntactic sugar. removed need for
    • return keyword
    • function keyword
    • curly brackets

When not to use arrow function

Object Methods

const mario = {
    lives: 3,
    oneUp: () => {
        this.lives++; // this will not update lives
    }
}
  • Arrow function do not have their own this
  • this.lives will refer to outer environment

Object prototype

Dynamic context

  • arrow functions bind context statically. ie upon function declaration

When not to use arrow functionsQuestion that provoked this thought

char -> code

'a'.charCodeAt(0) // 97

code -> char

String.fromCharCode(97) // 'a'

char -> code

'a'.charCodeAt(0) // 97

code -> char

String.fromCharCode(97) // 'a'

Bit

5 << 2 // 101 << 2 // 010100 // 16+4 //20
5 >> 2 // 101 >> 2 // 01 // 2
5 ^ 3 // 101 ^ 011 // 0110 // 6
5 & 3 // 101 & 011 // 001 // 1 // always smaller or equal number
5 | 3 // 101 | 011 // 111 // 7 // always bigger or equal number
0 ^ 0 // 0
1 ^ 1 // 0

Bit

5 << 2 // 101 << 2 // 010100 // 16+4 //20
5 >> 2 // 101 >> 2 // 01 // 2
5 ^ 3 // 101 ^ 011 // 0110 // 6
5 & 3 // 101 & 011 // 001 // 1 // always smaller or equal number
5 | 3 // 101 | 011 // 111 // 7 // always bigger or equal number
0 ^ 0 // 0
1 ^ 1 // 0

what are callbacks?

  • Callbacks are the functions that are slipped or passed into another function to decide the invocation of that function.
  • example in filter, the callback function tells JavaScript the criteria for how to filter an array.

Related to lambda

what are callbacks?

  • Callbacks are the functions that are slipped or passed into another function to decide the invocation of that function.
  • example in filter, the callback function tells JavaScript the criteria for how to filter an array.

Related to lambda

class vs function

// Class syntax
class Person {
  constructor(first, last) {
    this.first = first
    this.last = last
    // we can put getFullName here
    // but then it'll be present on all object, wasting space
    // this.getFullName = function() {
    //     return `${this.first} ${this.last}`
    // }
  }
  getFullName() {
    return `${this.first} ${this.last}`
  }
}

//Equivalent function syntax
function Person(first, last) {
  this.first = first
  this.last = last
  // we can put getFullName here
  // but then it'll be present o all object, wasting space
}
Person.prototype.getFullName = function () {
  return `${this.first} ${this.last}`
}

class vs function

// Class syntax
class Person {
  constructor(first, last) {
    this.first = first
    this.last = last
    // we can put getFullName here
    // but then it'll be present on all object, wasting space
    // this.getFullName = function() {
    //     return `${this.first} ${this.last}`
    // }
  }
  getFullName() {
    return `${this.first} ${this.last}`
  }
}

//Equivalent function syntax
function Person(first, last) {
  this.first = first
  this.last = last
  // we can put getFullName here
  // but then it'll be present o all object, wasting space
}
Person.prototype.getFullName = function () {
  return `${this.first} ${this.last}`
}

what is closure?

  • ability of function to remember value of variable
  • ability to remember even after the outer function is executed is called closure
  • record storing a function together with environment
let Person = function(pName){
    let name = pName
    this.getName = function(){
        return name;
    }
}
let person = new Person("Sanyam")
person.getName() // "Sanyam"
  • helps in data privacy
  • helps in currying
  • could we create objects if closure was not provided by JS?
  • make public prop private by creating variable within constructor function
// old
function Bird(){
    this.name = 'donald'
}
b = new Bird()
b.name // "donald", can be modified also

// better + secure
function Bird(){
    let name = 'donald'
    this.getName = function(){
        return name
    }
}
b = new Bird()
b.name // undefined

what is closure?

  • ability of function to remember value of variable
  • ability to remember even after the outer function is executed is called closure
  • record storing a function together with environment
let Person = function(pName){
    let name = pName
    this.getName = function(){
        return name;
    }
}
let person = new Person("Sanyam")
person.getName() // "Sanyam"
  • helps in data privacy
  • helps in currying
  • could we create objects if closure was not provided by JS?
  • make public prop private by creating variable within constructor function
// old
function Bird(){
    this.name = 'donald'
}
b = new Bird()
b.name // "donald", can be modified also

// better + secure
function Bird(){
    let name = 'donald'
    this.getName = function(){
        return name
    }
}
b = new Bird()
b.name // undefined

Constructor property on objects

  • used to get reference to the constructor that created this object
let duck = new Bird()
let beagle = new Dog()
console.log(duck.constructor === Bird)
console.log(beagle.constructor === Dog)
  • can be overwritten, therefore better to use instanceof method to check type of object

objects can be created without constructor

var superProto = {
    name:'sanyam'
}
superProto.constructor // Object(){}

Constructor property on objects

  • used to get reference to the constructor that created this object
let duck = new Bird()
let beagle = new Dog()
console.log(duck.constructor === Bird)
console.log(beagle.constructor === Dog)
  • can be overwritten, therefore better to use instanceof method to check type of object

objects can be created without constructor

var superProto = {
    name:'sanyam'
}
superProto.constructor // Object(){}

Multiple constructor possible?

No. Since function overloading is not present we can have only Single constructor.

Hack

  • js function can take any number of arguments
  • it becomes duty of developer to check parameters and work accordingly
// normal way
function Student(name) {
  this.name = name
  this.age = 24
}

// if params are not fixed
function Student(name, age) {
  if (age === undefined) {
    age = 24
  }
  this.name = name
  this.age = age
}

Multiple constructor possible?

No. Since function overloading is not present we can have only Single constructor.

Hack

  • js function can take any number of arguments
  • it becomes duty of developer to check parameters and work accordingly
// normal way
function Student(name) {
  this.name = name
  this.age = 24
}

// if params are not fixed
function Student(name, age) {
  if (age === undefined) {
    age = 24
  }
  this.name = name
  this.age = age
}

creating a constructor

function that create new object

  • most important keyword is new, otherwise object won't be created
  • Defined with a capitalized name to distinguish from other functions that are not constructors.
  • Constructors use the keyword this to set properties of the object they will create. Inside the constructor, this refers to the new object it will create.
  • Constructors define properties and behaviors instead of returning a value as other functions might
  • properties are generally intialized with parameters
  • loosely they are like Java classes+constructor
function Animal(){
    this.name  = "goofy"
    this.numLegs = 2
}

creating a constructor

function that create new object

  • most important keyword is new, otherwise object won't be created
  • Defined with a capitalized name to distinguish from other functions that are not constructors.
  • Constructors use the keyword this to set properties of the object they will create. Inside the constructor, this refers to the new object it will create.
  • Constructors define properties and behaviors instead of returning a value as other functions might
  • properties are generally intialized with parameters
  • loosely they are like Java classes+constructor
function Animal(){
    this.name  = "goofy"
    this.numLegs = 2
}

what is currying?

currying function means, converting N parameter function to N functions with 1 parameter

  • very interesting! very clean with arrow functions
const add = x => y => z => x+y+z

where is it useful?

  • when you cannot supply all arguments to function at one time

cons

  • if param is increased, will have to change defination or wrap inside another function

what is currying?

currying function means, converting N parameter function to N functions with 1 parameter

  • very interesting! very clean with arrow functions
const add = x => y => z => x+y+z

where is it useful?

  • when you cannot supply all arguments to function at one time

cons

  • if param is increased, will have to change defination or wrap inside another function

Data Types

Primitives

- undefined
- null
- boolean
- Number
- String
- BigInt
- Symbol

Structural

- Object //anything made with new operator
- Function

Data Types

Primitives

- undefined
- null
- boolean
- Number
- String
- BigInt
- Symbol

Structural

- Object //anything made with new operator
- Function

Debugging

  • console.log()
  • console.clear()
  • typeof
  • === vs ==; === checks for type as well as value. == checks only for value
  • falsy values: false, 0, "", NaN, undefined, null

Debugging

  • console.log()
  • console.clear()
  • typeof
  • === vs ==; === checks for type as well as value. == checks only for value
  • falsy values: false, 0, "", NaN, undefined, null

for..in vs for..of

for(let i in object) // key

for(let i of object) // Error. Object is not iterable

for(let i in array) // index

for(let i of array) // item
  • in is a keyword used to get property

for..in vs for..of

for(let i in object) // key

for(let i of object) // Error. Object is not iterable

for(let i in array) // index

for(let i of array) // item
  • in is a keyword used to get property

what are first class functions?

  • functions that can
    • be assigned to a variable
    • passed into another function
    • returned from another function like normal value
  • in js, all functions are first class functions

what are first class functions?

  • functions that can
    • be assigned to a variable
    • passed into another function
    • returned from another function like normal value
  • in js, all functions are first class functions

what are functions in JS?

  • functions are special type of object
  • the code you write for function, isn't the actual function
    • it is an object with properties
    • They property is invocable.

what are functions in JS?

  • functions are special type of object
  • the code you write for function, isn't the actual function
    • it is an object with properties
    • They property is invocable.

hasOwnProperty

function Bird(name) {
  this.name = name;
  this.numLegs = 2;
}

let canary = new Bird("Tweety");


canary.hasOwnProperty('name') //true

'age' in canary //true or false
                //based on whether it is present in prototype chain
                //or not

can be confused with

  • in keyword
    • in checks complete prototype chain.
    • hasOwnProperty checks properties on current object
function Bird(name) {
  this.name = name;  //own property
}

Bird.prototype.numLegs = 2; // prototype property
b = new Bird()
b.hasOwnProperty('name') // true
b.hasOwnProperty('numLegs') // false
'name' in b // true
'numLegs' in b // true

hasOwnProperty

function Bird(name) {
  this.name = name;
  this.numLegs = 2;
}

let canary = new Bird("Tweety");


canary.hasOwnProperty('name') //true

'age' in canary //true or false
                //based on whether it is present in prototype chain
                //or not

can be confused with

  • in keyword
    • in checks complete prototype chain.
    • hasOwnProperty checks properties on current object
function Bird(name) {
  this.name = name;  //own property
}

Bird.prototype.numLegs = 2; // prototype property
b = new Bird()
b.hasOwnProperty('name') // true
b.hasOwnProperty('numLegs') // false
'name' in b // true
'numLegs' in b // true

Map (key, value)

  • set, get
const hashmap = new Map()
hashmap.set('sanyam', 30)
hashmap.get('sanyam') // 30

hashmap.has('sanyam') // true
hashmap.size // 1
for (const [key, value] of hashmap) {
  console.log('key,value', key, value)
}
hashmap.get('anisha') // undefined
hashmap.delete('sanyam')

Set (value)

  • used when you just want to check existence
  • add
const set = new Set()
set.add('sanyam')

set.has('sanyam') // true
set.size // 1
set.delete('sanyam')

const a = [1, 2, 1, 2]
const unique = new Set(a) //{1,2}

Map (key, value)

  • set, get
const hashmap = new Map()
hashmap.set('sanyam', 30)
hashmap.get('sanyam') // 30

hashmap.has('sanyam') // true
hashmap.size // 1
for (const [key, value] of hashmap) {
  console.log('key,value', key, value)
}
hashmap.get('anisha') // undefined
hashmap.delete('sanyam')

Set (value)

  • used when you just want to check existence
  • add
const set = new Set()
set.add('sanyam')

set.has('sanyam') // true
set.size // 1
set.delete('sanyam')

const a = [1, 2, 1, 2]
const unique = new Set(a) //{1,2}

what are higher order functions?

  • functions that
    • take function as argument
    • or return function as value

what are higher order functions?

  • functions that
    • take function as argument
    • or return function as value

what is hoisting?

  • able to access a variable before declaration
  • js raises up(hoists) the declarations
catName('kitty') // cat name is kitty
function catName(name){
    console.log('cat name is', name)
}
  • works with function & var. does not work with let, const

what is hoisting?

  • able to access a variable before declaration
  • js raises up(hoists) the declarations
catName('kitty') // cat name is kitty
function catName(name){
    console.log('cat name is', name)
}
  • works with function & var. does not work with let, const

iife -> Immediately Invoked Function Expression

usage

  • group related functionality into single object or module

doubt

  • why can't we use {} directly

iife -> Immediately Invoked Function Expression

usage

  • group related functionality into single object or module

doubt

  • why can't we use {} directly

inhertiance

using functions

    // let animal = new Animal() // has some disadvantage, therefore not used
    // 1. Create Instance of parent
    let Animal = function(){}
    Animal.prototype.eat = function(){
        return 'nom nom'
    }

    // 2. Set prototype of child to be instance of parent & update constructor
    let Bird = function(){}
    Bird.prototype = Object.create(Animal.prototype)
    Bird.prototype.constructor = Bird

    // 3. add own methods
    Bird.prototype.fly = function(){
        return 'i can fly'
    }

    // 4. Override parent method
    Bird.prototype.eat = function(){
        return 'eating nicely'
    }

above example using classes

class Animal{
    eat(){
        return 'nom nom'
    }
}
class Bird extends Animal{
    fly(){
        return 'I can fly!'
    }
    // override
    eat(){
        return 'burp burp'
    }
}

Mixin

  • added to object not constructor, therefore protoype is not used
  • add unrelated function to both obj
let flyMixin = function(obj){
    obj.fly = function(){
        console.log('i am flying')
    }
}
flyMixin(bird)
flyMixin(airplane)

inhertiance

using functions

    // let animal = new Animal() // has some disadvantage, therefore not used
    // 1. Create Instance of parent
    let Animal = function(){}
    Animal.prototype.eat = function(){
        return 'nom nom'
    }

    // 2. Set prototype of child to be instance of parent & update constructor
    let Bird = function(){}
    Bird.prototype = Object.create(Animal.prototype)
    Bird.prototype.constructor = Bird

    // 3. add own methods
    Bird.prototype.fly = function(){
        return 'i can fly'
    }

    // 4. Override parent method
    Bird.prototype.eat = function(){
        return 'eating nicely'
    }

above example using classes

class Animal{
    eat(){
        return 'nom nom'
    }
}
class Bird extends Animal{
    fly(){
        return 'I can fly!'
    }
    // override
    eat(){
        return 'burp burp'
    }
}

Mixin

  • added to object not constructor, therefore protoype is not used
  • add unrelated function to both obj
let flyMixin = function(obj){
    obj.fly = function(){
        console.log('i am flying')
    }
}
flyMixin(bird)
flyMixin(airplane)

instanceof

  • complete keyword is in lower case
let a = new Animal()
a instanceof Object //true
a instanceof Animal //true
a instanceof People //false

instanceof

  • complete keyword is in lower case
let a = new Animal()
a instanceof Object //true
a instanceof Animal //true
a instanceof People //false

isPrototypeOf

  • generally used when you don't have constructor functions
Dog.prototype.isPrototypeOf(beagle) // with constructor function, use prototype
beagle.isPrototypeOf(goofy) // can directly used with object
  • all objects have prototype
  • prototype is an object
  • therefore an object's prototype can have its own prototype
object.prototype.prototype
  • when you don't have constructor function to use with instanceof
var superProto = {
    // some super properties
}

var subProto = Object.create(superProto);
subProto.someProp = 5;

var sub = Object.create(subProto);

console.log(superProto.isPrototypeOf(sub));  // **true**
console.log(sub instanceof superProto);      // TypeError
console.log(sub instanceof superProto.constructor)  // true

isPrototypeOf

  • generally used when you don't have constructor functions
Dog.prototype.isPrototypeOf(beagle) // with constructor function, use prototype
beagle.isPrototypeOf(goofy) // can directly used with object
  • all objects have prototype
  • prototype is an object
  • therefore an object's prototype can have its own prototype
object.prototype.prototype
  • when you don't have constructor function to use with instanceof
var superProto = {
    // some super properties
}

var subProto = Object.create(superProto);
subProto.someProp = 5;

var sub = Object.create(subProto);

console.log(superProto.isPrototypeOf(sub));  // **true**
console.log(sub instanceof superProto);      // TypeError
console.log(sub instanceof superProto.constructor)  // true

what is lambda?

  • functions that are passed as argument or returned as value

lambda vs callbacks

  • lambda - anonymous
  • callbacks - named or anonymous
  • all lambda can be callback but not all callback may be lambda

what is lambda?

  • functions that are passed as argument or returned as value

lambda vs callbacks

  • lambda - anonymous
  • callbacks - named or anonymous
  • all lambda can be callback but not all callback may be lambda

what is memoization?

  • optimizing technique used to speed up program by storing result of expensive function
  • return cached result when same input occurs
  • built on 2 concepts
    • closure
    • higher order functions
function memorizer(fun) {
  let cache = {}
  return function (n) {
    if (cache[n] !== undefined) {
      return cache[n]
    }
    let result = fun(n)
    cache[n] = result
    return result
  }
}
const addOne = memorizer((num: number) => num + 1)
  • first call takes time but for next calls, result comes from cache

what is memoization?

  • optimizing technique used to speed up program by storing result of expensive function
  • return cached result when same input occurs
  • built on 2 concepts
    • closure
    • higher order functions
function memorizer(fun) {
  let cache = {}
  return function (n) {
    if (cache[n] !== undefined) {
      return cache[n]
    }
    let result = fun(n)
    cache[n] = result
    return result
  }
}
const addOne = memorizer((num: number) => num + 1)
  • first call takes time but for next calls, result comes from cache

use of new keyword

  • When using new, this refers to the new empty object we create. However, if you don't add new, this refers to the global object!
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}
const sarah = Person('Sarah', 'Smith');
console.log(sarah); // undefined, since Person didn't return anything
console.log(this.firstName); //'Sarah', sicne firstName is now defined on global/window object

use of new keyword

  • When using new, this refers to the new empty object we create. However, if you don't add new, this refers to the global object!
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}
const sarah = Person('Sarah', 'Smith');
console.log(sarah); // undefined, since Person didn't return anything
console.log(this.firstName); //'Sarah', sicne firstName is now defined on global/window object

what is Object.create()

  • used to create object, using existing object as prototype
const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`)
  },
}

const me = Object.create(person)

me.name = 'Matthew' // "name" is a property set on "me", but not on "person"
me.isHuman = true // inherited properties can be overwritten

me.printIntroduction()
// expected output: "My name is Matthew. Am I human? true"

what is Object.create()

  • used to create object, using existing object as prototype
const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`)
  },
}

const me = Object.create(person)

me.name = 'Matthew' // "name" is a property set on "me", but not on "person"
me.isHuman = true // inherited properties can be overwritten

me.printIntroduction()
// expected output: "My name is Matthew. Am I human? true"

object: make copy

  • Object.assign(target, source1, source2)
    • if target is not {}, it'll modify target
    • target, source1. then target, source2. therefore keys from source2 will take precendence

object: make copy

  • Object.assign(target, source1, source2)
    • if target is not {}, it'll modify target
    • target, source1. then target, source2. therefore keys from source2 will take precendence

Prototype properties

  • properties in prototype are shared among all the objects
ConstructorName.prototype.propertyName = value
  • cannot add from object, needs to be added from constructor

pros

  • helps in saving memory
  • reducing duplicate variables
  • hasOwnProperty
// instead of adding each property manually, we can overwrite it with new object
Dog.prototype = {
    numLegs:4,
    eat:function(){
        console.log('eat eat eat')
    },
    describe:function(){
        console.log('my name is'+this.name)
    }
}

but problem with above is that constructor property is lost, therefore we redefine it

// instead of adding each property manually, we can overwrite it with new object
Dog.prototype = {
    constructor: Dog,
    numLegs:4,
    eat:function(){
        console.log('eat eat eat')
    },
    describe:function(){
        console.log('my name is'+this.name)
    }
}

Prototype properties

  • properties in prototype are shared among all the objects
ConstructorName.prototype.propertyName = value
  • cannot add from object, needs to be added from constructor

pros

  • helps in saving memory
  • reducing duplicate variables
  • hasOwnProperty
// instead of adding each property manually, we can overwrite it with new object
Dog.prototype = {
    numLegs:4,
    eat:function(){
        console.log('eat eat eat')
    },
    describe:function(){
        console.log('my name is'+this.name)
    }
}

but problem with above is that constructor property is lost, therefore we redefine it

// instead of adding each property manually, we can overwrite it with new object
Dog.prototype = {
    constructor: Dog,
    numLegs:4,
    eat:function(){
        console.log('eat eat eat')
    },
    describe:function(){
        console.log('my name is'+this.name)
    }
}

regex

  • Single Match
    const index = 'Some text'.search(regex)
    returns int-> -1 or i>=0
    
    • no use of /g
  • Multiple match
    const matches = 'Some text'.match(regex)
    returns null or {index:3, input:'Some text'}
    
    • returns multiple match if /g
  • replace
    const next = 'Some text'.replace(regex,'hi mom')
    
  • regex
    const regex = /bob/g -> match bob
    const regex = /bob|alice/g -> match bob or alice
    const regex = /(bob|alice) Jones/g -> match bob jones or alice jones
    const regex = /colou?r/g -> matches color, colour ?-> 0 or 1
    const regex = /color*/ -> matches color, colorrr *-> 0 or multiple
    const regex = /color+/ -> matches color, colorrr +-> 1 or multiple
    const regex = /color{2,3}/ -> matches colorr, colorrr, but not color {min, mix}
    \ -> escape special character
    \d -> digit
    \w -> word character
    \D -> not digit
    \W -> not word character
    [A-Z] -> b/w a-z
    [^A-Z]-> not b/w a-z
    
  • 2 ways to created
    1. literal notion
    /sanyam/gi
    
    • used when it will remain constant
    • ex: in loops
    1. constructor function
    new RegExp('sanyam','gi')
    

regex

  • Single Match
    const index = 'Some text'.search(regex)
    returns int-> -1 or i>=0
    
    • no use of /g
  • Multiple match
    const matches = 'Some text'.match(regex)
    returns null or {index:3, input:'Some text'}
    
    • returns multiple match if /g
  • replace
    const next = 'Some text'.replace(regex,'hi mom')
    
  • regex
    const regex = /bob/g -> match bob
    const regex = /bob|alice/g -> match bob or alice
    const regex = /(bob|alice) Jones/g -> match bob jones or alice jones
    const regex = /colou?r/g -> matches color, colour ?-> 0 or 1
    const regex = /color*/ -> matches color, colorrr *-> 0 or multiple
    const regex = /color+/ -> matches color, colorrr +-> 1 or multiple
    const regex = /color{2,3}/ -> matches colorr, colorrr, but not color {min, mix}
    \ -> escape special character
    \d -> digit
    \w -> word character
    \D -> not digit
    \W -> not word character
    [A-Z] -> b/w a-z
    [^A-Z]-> not b/w a-z
    
  • 2 ways to created
    1. literal notion
    /sanyam/gi
    
    • used when it will remain constant
    • ex: in loops
    1. constructor function
    new RegExp('sanyam','gi')
    

Array.prototype.sort()

  • does in place & also returns sorted array
  • sorting is peculiar
    • converts elements to string, then compares them
    • sorts in ascending order
const months = ['March', 'Jan', 'Feb', 'Dec']
months.sort() // ["Dec", "Feb", "Jan", "March"]

const nums = [1, 30, 4, 21, 100000]
nums.sort() // [1, 100000, 21, 30, 4]

We can see, Numbers are not sorted!

Correct way to sort num array

nums.sort((first, second) => first - second)

Correct way to sort date array

dates.sort((first, second) => new Date(first) - new Date(second))

correct way to sort string

strings.sort((first, second))=>{
  if(first<second){
    // natural order is ascending order. here we do not want to change anything so return -1
    return -1
  }
  return 1
})

functional. requires a callback to sort

Array.prototype.sort()

  • does in place & also returns sorted array
  • sorting is peculiar
    • converts elements to string, then compares them
    • sorts in ascending order
const months = ['March', 'Jan', 'Feb', 'Dec']
months.sort() // ["Dec", "Feb", "Jan", "March"]

const nums = [1, 30, 4, 21, 100000]
nums.sort() // [1, 100000, 21, 30, 4]

We can see, Numbers are not sorted!

Correct way to sort num array

nums.sort((first, second) => first - second)

Correct way to sort date array

dates.sort((first, second) => new Date(first) - new Date(second))

correct way to sort string

strings.sort((first, second))=>{
  if(first<second){
    // natural order is ascending order. here we do not want to change anything so return -1
    return -1
  }
  return 1
})

functional. requires a callback to sort

Spread Syntax

  • Allows spreading array, string
let a = [1, 2, 3]
console.log(a) //[1,2,3]
console.log(...a) //1 2 3
let b = 'sanyam'
console.log(b) //sanyam
console.log(...b) //s a n y a m
let c = { name: 'sanyam' }
let d = { age: 20 }
console.log({ ...c, ...d }) //{'name':'sanyam':'age':20}
console.log(...c) // Error: non-callable iterator
  • better than Function.prototype.apply(context, array)
    • used to mainly call function with array as arugment
      function sum(x, y, z) {
        return x + y + z
      }
      
      const numbers = [1, 2, 3]
      
      console.log(sum(...numbers))
      // expected output: 6
      
      console.log(sum.apply(null, numbers))
      // expected output: 6
      

MDN on Spread_Syntax

Spread Syntax

  • Allows spreading array, string
let a = [1, 2, 3]
console.log(a) //[1,2,3]
console.log(...a) //1 2 3
let b = 'sanyam'
console.log(b) //sanyam
console.log(...b) //s a n y a m
let c = { name: 'sanyam' }
let d = { age: 20 }
console.log({ ...c, ...d }) //{'name':'sanyam':'age':20}
console.log(...c) // Error: non-callable iterator
  • better than Function.prototype.apply(context, array)
    • used to mainly call function with array as arugment
      function sum(x, y, z) {
        return x + y + z
      }
      
      const numbers = [1, 2, 3]
      
      console.log(sum(...numbers))
      // expected output: 6
      
      console.log(sum.apply(null, numbers))
      // expected output: 6
      

MDN on Spread_Syntax

Static method

  • live only on constructor they are created
  • cannot be passed down to their children

Static method

  • live only on constructor they are created
  • cannot be passed down to their children