Sunday, 27 September 2020

Javascript Basics

 


1.Property Access :


what is an object ?


An object is a data structure.

we have key value pairs.we store our data in there.

And that data we store at those property names can be any type.



Accessing properties on an Object :


There are two ways to access properties on an object 


1.Dot Notation

2.Bracket Notation/ Square bracket Notation

Note : Always use Dot Notation.But if you're dealing with invalid identifier

or variables,use the Bracket notation.

Dot Notation :

Use can Assign and access properties on an object using Dot Notation 

ex : assignment with dot

var box={};

box.material ="cardboard";

var box = {"material":"cardboard"};


ex: access with dot



var box={};

box.material ="cardboard";


var cb = box.material;

console.log(cb);      //  cardboard


Brackets :


ex: var box ={};

    box["material"] = "cardboard";

console.log(box.material);    // cardboard

    console.log(box["material"]); // cardboard


ex : variables


     var box ={};

box["material"] ="cardboard";

var key = "material";

console.log(box[key]);  // "cardboard"


ex: expressions


    var box ={};

    box["material"]="cardboard";

    var func = function(){

  return "material";

}

   console.log(box[ func() ]);   // "cardboard"



ex :  

      var box ={};

      box['material'] ="cardboard";

      var key ='material';

      console.log(box['key']);   // undefined

  console.log(box.key);        // undefined

  console.log(box[key]);      // "cardboard"


Note : if property doesn't exist on object , so it returns undefined.


Dot notation :


1.Property identifies can only be alphanumeric (_ and $).

2.Property identifiers cannot start with number

3.Property identifiers cannot contain variables.

  ex: obj.prop_1, obj.prop$


Bracket Notation :


1.Property identifiers have to be a string or a variable that references a string.

2.It is okay to use variables,spaces and strings that start with numbers.

 ex: obj["1prop"],obj{"prop Name"]


summary :

1.Dot notation is faster to write and clearer to read.

2.Square bracket notation allows access to properties containing special characters and selection of properties using variables.

3.Bracket notation expects an expression which evaluates to a string.

4.The dot notation only works with property names which are valid identifier name.


Brackets : quotes('') required for strings,weired characters.

           quotes('') not required for variables,numbers and expressions.


Storing Data and Object-literal Notation :


we can store any data in our object.


 ex: 

    var box = {};

box["material"]="cardboard";

box["size"] = {

  "height" : 2,

  "width" : 80

};

box.area= function(){

   return box.size.height * box.size.width;

};

or 

box['area'] = function(){

   return box.size.height * box.size.width;

};


Access function :


ex :

   box["area"]();

    

   var func = 'area';

   box[func]();

   


Note :


1.Objects created using object literals are singletons.

This means when a change is made to the object,it affects that object across the entire script.


2.Object defined with the function constructor let us have multiple instances of that object.

This means change made to one instance, will not affect other instances.


Object literal Notation

  

 ex : 

    var box = {

material: "cardboard",

height    : 2,

width     : 80,

area    : function(){

   return this.height * this.width;

  }

};


what are the different ways you can add properties and values to objects?


--> dot notation and bracket notation.


which of these methods would you use if you wanted to add a property to an object that had a weired symbol ('&')?


--> must use bracket notation


what about if the property is a variable, how does that change the syntax ?


--> must use bracket notation, no quotes


 

Object Iteration :


1. for..in loop

    

ex : 

var box = {

material: "cardboard",

height    : 2,

width     : 80

};


  for (let key in box){

      console.log(key, box[key]);  // prints key and value 

   }    


2.with ES6 for..of using Object.entries


  ex : 

    var box = {

material: "cardboard",

height    : 2,

width     : 80

};


  for (let [key,value] of object.entries(box)){

      console.log(key,value);  // prints key and value 

   }       

 

Note : 

The keys,values and entries are 3 common lists to extract from a javascript objects.


1. The keys of an object is the list of property names.

2. The values of an object is the list of property values.

3. The entries of an object is the list of pairs of property names and corresponding values.


1.Object.keys() returns keys

2.Object.values() returns value

3.Object.entries() returns entries

 

or 


1.The keys are returned by Object.keys(object)

2.The values are returned by Object.values(object)

3.The entries are returned by Object.entries(object)




 

Arrays :

==========


Arrays are a special type of objects, with numbered indexes.


Array is an object which is used to store a collection of values or items in a single variable.


Arrays allow us to store values without needing to assign keys.


 ex :

  let box = [];

  box[0] = true;

  box[1] = 'meow';

  box.push({'hello':'goodbye'});


   

  console.log(box[0]);  // true;

  console.log(box[1]);   // 'meow'

  console.log(box.pop());  // {'hello':'goodbye'}

  

Note : pop() method remove an item from the end of an array.  

  

  console.log(box); // [true,'meow'];


  

Note : push() method append items to the end of an array.  

       you can use push() method to append more than one item/value to an array in a single call.


ex: 

// initialize array

let arr = ["Hi", "Hello", "Bonjour", "Hola"];


// append multiple values to the array

arr.push("Salut", "Hey"); 

   

 

 ex :       var box=[];

            box['size'] =9;

box['0'] = 'meow';

console.log(box) ; // ["meow", size: 9] 

console.log(box['size']) // 9

console.log(box[0]);      // 'meow'


Note : An array is an object that means you can add properties to it.


 ex :  var box=[];

       box['size']=9;

       box['0']='meow';

   console.log(box)  // ["meow", size: 9]

       box.size;  // 9

       box[0];   // 'meow'    

   

Iteration :


ex :


  var box=[];

  box['size'] =9;

  box['0']='meow';

  for(let key in box){

   console.log(key);    // 0,size

  } 


  for(let key in box){

   console.log(box[key]);    // meow,9

  } 


Native properties :


  ex : var box =[];

       box['0']='meow';

       box[3]={'babyBox':true};

       box['length']; // 4


Note : The array length property is keeping track of the numerical indices,

every time you add something to it.


  ex : 

       var box =[];

   box['0'] = 'meow';

   box[1] = {'babyBox': true};

   box[length]; // undefined


The length variable is not defined/declared .


ex : var box =[];

     box['0'] = 'meow';

     box[1] = {'babyBox': true};

     box[box.length-1];  // {babyBox: true}


How to add values & indices to arrays ?


1.bracket notation

2.bracket notation with variable

3.dot notation

4.native methods

5.length property


How to access values & indices to arrays ?


1.bracket notation

2.bracket notation with variable

3.dot notation

4.native methods

5.length property



Create an array 


 ex : let noiseArray =['purr'];


Add item to the beginning of an Array


 ex : noiseArray.unshift('hiss');


Add item to the end of an array.


 ex : noiseArray.push('meow');


Using bracket notation add item to an array.


ex :  noiseArray[3] ='growl';


Inspect an Array :


1. length of an array.


 ex : let totalitems = noiseArray.length;

 

 index starts from 0 so the last index is 1 less than the length.

 

 Nest the array in the object

 

  ex : animal.noises = noiseArray;

       console.log(animal);


What are the different ways you can add properties and values to arrays?


use bracket notation or native array methods    


Come up with two ways you can add an element to the end of an array, without knowing the exact length of the array.


 use arr.push() or arr[arr.length]



Functions :

==========


parameters are variables listed as a part of the function definition.


Arguments are values passed to the function when it is invoked.


The arguments object is an array-like construct which can be used to access arguments 

passed to the function even if a matching parameter isn't explicitly defined.


The "argument object" is an array-like object that stores all the parameters passed to a function.

even if the function declaration doesn't specify any parameters.


function argumentVar(parameter1, parameter2, parameter3){

  console.log(arguments.length); // Logs the number of arguments passed.

  console.log(arguments[3]); // Logs the 4th argument. Follows array indexing notations. 

}


argumentVar(1,2,3,4,5);

// Log would be as follows

// 5

// 4


ex :


function addAlltheNumbers(){

  var argsArray = Array.prototype.slice.call(arguments);

  return argsArray.reduce( (acc,cur) => acc + cur);

  

}

 

addAlltheNumbers(1543,3298,1729,1449,1435); // 10000


Constructor :


function AnimalMaker(name){

  return {

   speak : function (){

     console.log("my name is ", name);

   }  

  };


var myAnimal = AnimalMaker('tiger');


myAnimal.speak; // f(){ console.log("my name is ",name);}


myAnimal.speak(); // my name is tiger


ex :


function AnimalMaker(name){

  return {

   speak : function (){

     console.log("my name is ", name);

   }  

  };

}


var animalNames =['Sheep','Liger','Big Bird'];


var farm[];


for(let i =0; i < animalNames.length;i++){  

  farm.push(AnimalMaker(animalNames[i]));

}


for (let j=0; j<farm.length;j++){

  farm[j].speak();

}


ex :

  function AnimalTestUser(username){ 

     let args = arguments.length;

let otherArgs = [];

   if(args>1){

     for( let i=1;i<args;i++){

  otherArgs.push(arguments[i]);

}

   }

  

   return {

     username:username,

otherArgs:otherArgs

   };

  }

  

  

without arguments : 

   

  let myAnimal = AnimalTestUser('cow');

  console.log(  myAnimal.username); // cow


  

with arguments :


var testSheep = AnimalTestUser('CottonBall', {'loves dancing': true}, [1,2,3] );

console.log(testSheep);   ////{ username: 'CottonBall', otherArgs: [ {'loves dancing': true}, [1,2,3] ] }


ex: 


function AnimalCreator(username,species,tagline,noises){

  var animal = {

   username:username,

   species : species,

   tagline : tagline,

   noises : noises,

   friends : []

  };

  

  return animal;

}


let sheep = AnimalCreator('Cloud','sheep','you can count on me!',['baahhh','arrgg','chewchewchew']);


console.log(sheep);   

      // { username: 'Cloud', 

      //  species: 'sheep', 

      //  tagline: 'You can count on me!', 

      //  noises: ['baahhh', 'arrgg', 'chewchewchew'], 

      //  friends: []

      // }

   

 function addFriend(animal,friend){

     animal.friends.push(friend.username);

 } 

       

let cow = AnimalCreator('Moo','cow','got milk?',['moo','moooo','mooo']);


let llama= AnimalCreator('Zeny','llma','llll',['sdf','sdfsf']);


addFriend(sheep,cow);

addFriend(sheep,llama);


let myFarm = [sheep,cow,llama];

addFriend(cow,sheep);

addFriend(llama,cow);


function addMatchesArray(farm){

   for(let animal in farm){

   farm[animal].matches=[];

   }

}

addMatchesArray(myFarm);

console.log(myFarm[0]);


function giveMatches(farm){

  for(let animal in farm){

   farm[animal].matches.push(farm[animal].friends[0]);

   

  }

}


giveMatches(myFarm);

console.log(myFarm[0]);


Nesting :

===========

 ex: var box = {};

     box.innerBox={};

 

( or)

var box = {"innerBox":{}};

   ex: 

    var box ={};

    box['innerBox']={};


ex :

    var box ={};

    box['innerBox'] ={};

    box['innerBox']['full']=true;


    (or)

    var box = { 'innerBox':{full:true}};


Scope :

=========

Scope is created dynamically whenever we call the function.


A function has access to its own local scope variables.


Different Types of Scopes :


1.Global Scope

2.Function Scope(local scope)

3.Module Scope

4.Block Scope

5.Lexical Scope


Scope is the region of the codebase over which an identifier is valid.


1.Global Context :


Variables declared directly in the global context, in which case they are added as properties on the global context.


Global Variables are available for the lifetime of the application.


There is only one Global scope throughout a javascript document.

A variable is in the Global scope if it's defined outside of a function.


Note : You can also access and alter any variable declared in a global scope from any other scope.


ex : 

    function f1(){

console.log(' I am global function');

}

f1();        // I am global function

window.f1(); // I am global function

 ex: 

     var x ='global !';

     function encapsulate(){

   z =' global here, too !';

   window.y='also global';

}  


2.Function Scope :


Variables defined in a function are visible everywhere within the function,

but are not visible outside of the function.


Variables declared within a function are in the local scope.

Local scope is also called function scope because local scope is created by functions in Javascript.


ex: 

     var func = function(){

    var local = true;

}


Note : 

1.Variables declared with 'var' have only function scope.

2.Variables declared with 'var' hoisted to the top of their scope.  



3.Block Scope :


A block is a set of opening and closing curly brackets.


In ES6, 'let' and 'const' keywaords allow developers to declare variables in the block scope,

which means those varaiables exist only within the corresponding block.


A block scope is the area within 'If','switch', conditions or 'for' and 'while' loops.


ex : function foo(){

      if(true){

    var fruit1 ='apple';       // exist in function scope

let fruit2 ='banana';      // exist in block scope

const fruit3='strawberry'; // exist in block scope

  }

  console.log(fruit1);

  console.log(fruit2);

  console.log(fruit3);

 

    }


// Result :

   // apple

   // error: fruit2 is not defined

   // error: fruit3 is not defined


Block scope is everything inside a set of braces.

   ex : { a block scope here }


Note : A Block scope is sometimes the same as a function scope.

so, at the top of a function's code, a block scope will be the same as a function scope.


ex : 

     function test(x){

// this is both a block scope and a function scope

let y = 5;

if(x){

   // this is a smaller block scope that is not the same as the function scope

   let z=1;

  }  


Note :

'var' is not limited to the curly brackets.

'var' is a function scope.

Function scope is within the function.

 

4.Lexical scope :

Lexical scope means the children scope have the 

access to the variables defined in the parent scope.


The children functions are lexically bound to the execution context of their parents.


This lexical scope is heavily used in closures in javascript.


ex : 

      function outerScope(){

    var name ='Juan';

function innerScope(){

  console.log(name ) ;    // Juan

}

    return innerScope;

  }

  

  const inner = outerScope();

  inner(); 


5.Module scope 

  With the introduction of modules in ES6, it was important for variables in a module to

  not directly affect variables in other modules.

  

  Modules create their own scope which encapsulate all variables created with

  var,let or const similar to the function scope.

  

  A module is just a file which can be imported from other modules (or files) through the help of directives

  like 'export' and 'import'.

       

 

Parent vs Child scope :


 ex : 

   function blender ( fruit){

     var b= fruit;

var y = 'yogurt';

function bs(){

   var x='asdf';

  console.log( b + ' and ' + y + ' Makes '+b+' swirl');

}

 

bs();

   

   } 

   

  blender('blueberry');  // blueberry and yogurt Makes blueberry swirl

  

  Note : child  scope can access variables from parent scope. but parent scope cannot access from child scope


 

Precedence :


The local variable always get priority over the global variables with same name.


if you declare a local variable and a global variable with the same name,

the local variable will take precedence when you use it inside a function.

This type of behavior is called shadowing(variable shadowing).


  ex : 

       var g ='global';

  

      function go(){

    var l ='local';

var g ='in here !';

console.log( g + " inside go");

  } 

      go(); // in here inside go   

     console.log( g + " outside go'); // global outside go

 

Note :  

The local variables always get priority over the global variables with same name.


Summary :


1. A function has access to its own local scope variables


 ex : var ACTUAL;

      var fn = function(){

    var name='inner';

ACTUAL=name;

console.log(ACTUAL);

  }

      fn();   // inner

  console.log(ACTUAL); // inner


2.Inputs to a function are treated as local scope variables.

  ex : 

       var ACTUAL;

   var fn=function(name){

     ACTUAL=name;

console.log('local scope',ACTUAL);

   }

   fn('inner');

  console.log('outer scope',ACTUAL); 

  Result :

     // local scope inner

     // outer scope inner

 

3.A function has access to the variables contained within the same scope that function was created in.


ex :  var ACTUAL;

      var name ='outer';

  var fn = function(){

    ACTUAL=name;

  }

  fn();

  console.log(ACTUAL); // outer


4. A function's local scope varaiables are not available anywhere outside that function.


ex : var firstFn = function(){

      var localToFirstFn = 'inner';

     }

     firstFn();

     console.log(localToFirstFn); // Uncaught ReferenceError: localToFirstFn is not defined


5.A function's local scope variables are not anywhere outside that function, regardless of the context it's called in.


 ex:  

     var ACTUAL;

      var firstFn=function(){

      var localToFirstFn = 'first';

  secondFn();

  }  

    var secondFn = function(){

   ACTUAL = localToFirstFn;

}

secondFn();  // Uncaught ReferenceError: localToFirstFn is not defined


Note : since secondFn does not have access to the localToFirstFn variable.

    

firstFn(); // Uncaught ReferenceError: localToFirstFn is not defined

Note : calling the firstFn(which in turn calls the secondFn) should also throw,

since it is calling context of secondFn has no influence over its scope access rules.


6. If an inner and outer variable share the same name,and the name is referenced in the inner scope,

the inner scope variable masks the variable from the outer scope with the same name.

This renders the outer scope variables inaccessible from anywhere within the inner function block.


ex : var ACTUAL;

     var sameName='outer';

     var fn = function(){

  var sameName='inner';

   ACTUAL=sameName;

};

    fn();

    console.log(ACTUAL); //  inner

7. if an inner and an outer variable share the same name,and the name is referenced

in the outer scope,the outer value binding will be used.


 ex : 

      var ACTUAL;

      var sameName='outer';

      var fn = function (){

    var sameName ='inner';

  }

      fn();

      ACTUAL=sameName;

      console.log(ACTUAL); // outer

  

8.A new variable scope is created for every call to a function,

as exemplified with a counter.


 ex : var ACTUAL;

      var fn = function(){

   var innerCounter = innerCounter || 10;

   innerCounter = innerCounter + 1;

   ACTUAL = innerCounter;

  } 

  fn();

  console.log(ACTUAL);  // 11

  fn();

  console.log(ACTUAL);  // 11

  

9.A new variable scope is created for each call to a function, as 

exemplified with uninitialized string variables.


  ex : var ACTUAL;

       var fn = function(){

     var localVariable;

if(localVariable === undefined){

   ACTUAL='alpha';

} else if (localVariable === 'initialized'){

  ACTUAL ='omega';

}

     localVariable='initialized';

   }

   

   fn();

   console.log(ACTUAL);  // alpha

   fn();

   console.log(ACTUAL);  // alpha


10. An inner function can access both its local scope variables and variables in its containing scope,

provided the variables have different names;


 ex : var outerName ='outer';

      var fn =function(){

   var innerName ='inner';

   ACTUAL = innerName + outerName;

  }  

  fn();

  console.log(ACTUAL); //innerouter

  

11. Between calls to an inner function, that inner function retains access to a variable in an outer scope.

Modifying those variables has a lasting effect between calls to the inner function.


  ex : var ACTUAL;

       var outerCounter = 10;

       var fn = function () {

      outerCounter = outerCounter+1;

  ACTUAL=outerCounter;

   }

       fn();

       console.log(ACTUAL);  // 11

       fn();

       console.log(ACTUAL);  // 12


12.The rule about retaining access to variables from an outer scope still applies,

even after the outer function call ( that created the outer scope) has returned.


  ex :  var ACTUAL;

        var outerFn = function(){

  var counterInOuterScope = 10;

  

  var innerIncrementingFn = function(){

    counterInOuterScope = counterInOuterScope + 1;

ACTUAL=counterInOuterScope;

  }

  

  innerIncrementingFn();

  console.log(ACTUAL);       // 11

  innerIncrementingFn();

   console.log(ACTUAL);      // 12

   window.retainedInnerFn = innerIncrementingFn;   

  

};

console.log(window.retainedInnerFn); // undefined

outerFn();

console.log(window.retainedInnerFn);  // function

window.retainedInnerFn();

console.log(ACTUAL);                  // 13

 

Closure :

===========

A closure happens when you return a function from inside of the function,

and that inner function retains access to the scope.


The closure has three scope chains :


1.it has access to its own scope.

2.it has access to the outer function scope.

3.it has access to the global scope.


Note : The inner function will have access to the variables in the outer function scope, even after the outer function has returned.


 ex : 

      var closureAlert = function(){

    var x = " Help! I'm a variable stuck in a closure!";

var alerter = function (){

  console.log(x);

}

setTimeout(alerter,1000);

console.log('will still run right after');

  };

   closureAlert();


Result :

  will still run right after

  Help! I'm a variable stuck in a closure!

    

 ex :

      var closureAlert = function (){

    var x = 0;

var alerter = function(){

  console.log(++x);

};

return alerter;

  };

   

      var funcStorer = closureAlert();

      var funcStorer2 = closureAlert();

      funcStorer(); // 1

      funcStorer();  // 2

  

  funcStorer2(); // 1


 ex : 

      var add = function(num){

    var num1=num;

var addToNum1 = function(num2){

  return num1 + num2;

};

return addToNum1;

  };

  

  var add5 = add(5);

  add5(2);    // 7

      add5(3);    // 8


Closure Object :


  ex :

  

   function counter(){

    var n =0;

return {

count : function() { return ++n;},

reset : function() { n =0; }

};   

   };   

  var myCounter = counter();

   myCounter.count();  // 1

   myCounter.count();  // 2

   myCounter.count();  // 3


Callbacks :

============


1. Module pattern :


Module pattern is a commonly used design pattern which is used to wrap a set of variables 

and functions together in a single scope.


Module pattern is used to define objects and specify the variables and the functions that can be accessed 

from outside the scope of the function.


we expose certain properties and function as public and can also restrict the scope of properties and functions within the object itself,making them private.

This means that those variables cannot be accessed outside the scope of the function.we can achieve data hiding an abstraction using this pattern in the javascript.


Benefits of module pattern :


1.Maintainability : 

2.Reusability



Higher-Order Functions :


1.takes a function as an input (argument)


  ex : element.addEventListener("click",function(){

        console.log("element clicked!");

       });  

2.Returns a function as an output


  ex : var add = function(num){

  

    var num1=num;

return addToNum1 = function(num2){

   return num1 + num2;

}

  };

  

Callbacks :


we can pass functions as parameters to other functions and call them inside the outer functions.


  ex :  var ifElse = function(condition, isTrue,isFalse){

             if(condition){

   isTrue;

}else{

   isFalse;

}

         }; 


          ifElse(true,function(){ console.log(true);},

                      function(){ console.lof(false);}

                 );



 ex : 

      const message = function(){

     console.log("this message is shown after 3 seconds");

  } 

  

  setTimeout(message,3000);

  

Note : The message function is a callback function.


 ex : Anonymous function 


      setTimeout(function(){

     console.log(" This message is shown after 3 seconds");

  },3000); 


The callback function here has no name and a function definition without a name in javascript

is called as an "anonymous function".   


  ex : callback as an Arrow function 

  

       setTimeout(()=>{

      console.log("this message is shown after 3 seconds");

   },3000);


you can write the callback function as an ES6 arrow function.


 ex : Events    

 

     <button id="callback-btn">Click here</button>

document.queryselector("#callback-btn")

      .addEventListener("click", function() {    

      console.log("User has clicked on the button!");

    });


callback  functions are used for event declarations in javascript.

Sunday, 20 September 2020

Arrays and Collections in Javascript

 


The Array.of() method creates a new Array instance with any number of arguments,regardless of their type.


ex : 

  let monthlySales = Array.of(12,9,3);

  let monthlyLabels = Array.of('Oct','Nov','Dec');

  let deptSales = Array.of(12,9,3);

  let deptLabels = Array.of('Hiking','Running','Hunting');

  

Using the spread Operator with array 


ex : 

     let monthlySales = Array.of(12,9,3);

 

let yearlyTotal= addYearlyTotal(...monthlySales);

 

 

function addYearlyTotal(a,b,c){

    return a+b+c;

}


ex :

      let octNums = Array.of(1200,1000,9000);

let novNums = Array.of(1100,2000,9000);

let decNums = Array.of(4000,1000,5000);

 

let total = Array.of(...octNums,...novNums,...decNums);


Using Array.find and Array.findIndex to find a value


ES6 Array.find() and Array.findIndex() methods which provide easy ways to search for an element in Javascript arrays.


Array.find() method returns the value of the first element in an array that passes a given test.


Note : 

1.Test must be provided as a function.

2.find() method executes a callback function once for each element in the array until it finds a value that returns true.

3.If nothing passes, undefined is returned.

4.find() does not mutate or change the original Array.


ex : 

     let monthlySales=Array.of(500,9000,3000)

     let firstThousand = monthlySales.find(element => element > 1000);

     console.log(firstThousand); // 9000


findIndex() returns the index of the first element in the array that satisfies the given test.


ex :  

let monthlySales=Array.of(500,9000,3000);

     let firstThousand = monthlySales.findIndex(element => element > 1000);

     console.log(firstThousand); // 2

 

Array.fill() :


you want to take an array and then just put all the numbers back to zero.


  ex : 

   let monthlySales=Array.of(500,9000,3000);

   monthlySales.fill(0);

   console.log(monthlySales); // [0, 0, 0]


Methods for Iterating through Arrays :


Array.forEach() is an Array method that we can use to execute a function on each element in an array.

it can only be used on Arrays,Maps and Sets.


ex :

const arr = ['cat', 'dog', 'fish'];

arr.forEach(element => {

  console.log(element);

});

// cat

// dog

// fish


ex :

       let monthlySales=Array.of(500,9000,3000);

       let yearlyTotal =0;

   

      function addYearlyTotal(x){

    yearlyTotal = x + yearlyTotal;

  }  

  

  monthlySales.forEach(addYearlyTotal);

  

  console.log(yearlyTotal);  // 12500


When using forEach, we simply have to specify a callback function.

This callback will be executed on each element in the array.


sets && WeakSets :


Sets enables you to store unique values of any type, whether primitive values or object references.


you can determine the size of the set by using the Size property.


ex : 

  const set1 = new Set(); 

  set1.add(42);

      set1.add('forty two');

      set1.add('forty two');

  console.log(set1.size);  // 2


Set Methods :

Add,clear,Delete,Entries,forEach,Has,Keys,Values


 ex : add

     

      const set1 = new Set();

  set1.add('3000');

  

  const test = new Set();

  test.add(5).add(4);

  

  const set2 = new Set(['5000','2000']);

   

 ex: delete


     const monthlySales = new Set();

monthlySales.add('5000');

monthlySales.delete('5000');


Iterating a set :

  ex :

    const monthlySales = new Set();

monthlySales.add('5000');

 

  for(let total of monthlySales)

  console.log(total);            // 5000

  

  monthlySales.forEach(element => {

    console.log( element);        // 5000

  });


Note : Array.from enables creating a new shallow-copied array from an array-like object 

or an iterable(Array,String,Map,Set) object.

  

  ex :

   const cars = new Set(['Porsche', 'Ferrari']);

   const carsCopy = Array.from(cars);

  console.log(carsCopy); // ["Porsche", "Ferrari"]

  

Set vs WeakSet :


WeakSet :

1.Only contains objects.

2.No primitive data types.

3.Objects are held 'weakly'.

4.Not iterable

5.No access to size property

6.Garbage collected


Weakset Methods : Add,Delete and Has


 ex : 

     const categories = new WeakSet();

  categories.add({category:'Hiking'});

  

  let running= { category:'Running'};   

      categories.add(running);

  console.log(categories.has(running)); // true



Using Maps in Javascript:


Map uses key-value pairs and keeps the original insertion order of the keys.

Any value (objects and primitive values) may be used as either a key or a value.


Map Methods :


Set,delete,clear,get,entries,forEach,has,keys,values


  ex: 

   const monthlySales = new Map();

   monthlySales.set('newsale',5000);

   console.log(monthlySales);        // {"newsale" => 5000}

   

   console.log(monthlySales.get('newsale')); // 5000


   console.log(monthlySales.has('newsale'));  // true

   

   monthlySales.delete('newsale');

   

Iterating through a Map :

 

   ex: 

     const monthlySales = new Map();

monthlySales.set('Oct',5000);

 

let arraydata= Array.from(monthlySales.keys());

console.log(arraydata);     // ["Oct"]


monthlySales.forEach( function(sale){

  console.log(sale);                    // 5000

});


     for(let amount of monthlySales.values()){

console.log(amount);                      // 5000

}


Weakmap :


1.Keys must be objects.

2.Object are held "weakly".

3.Not iteratable

4.Garbage collected

5.WeakMaps are not enumerable


WeakMap Methods : Set,get,has and delete


 ex : 

      const monthlySales = new WeakMap();

   

   let salesA= { a:[1,2]};

   monthlySales.set(salesA,'Hiking');

   console.log(monthlySales);   // {{...} => "Hiking"}


Saturday, 19 September 2020

Spread Operator in javascript

 1.Copy / concatenate arrays

2.pass to constructors

3.shallow copy objects

4.Call function with multiple parameters


The spread operator expands any iterable object such as a string

or an array into another array.


The spread operator used for passing multiple arguments to a method.


The syntax uses the ellipsis symbol (...) or three dots.


Always on the right-side of an equal sign.


Note : IE and Edge do NOT support spread operator.


ex : String to array

   let productNumber = "FR-R92B-58";

   let values =[...productNumber];

   console.log(values);  // ["F", "R", "-", "R", "9", "2", "B", "-", "5", "8"]


ex : Copy array 

    let arr = [1,2,3];

    let arr2= [...arr];

    // make changes to duplicated array

arr2.push(4);

arr2[0]=99;

 

   console.log(arr);    // [1, 2, 3]

   console.log(arr2);   //  [99, 2, 3, 4]


ex: copy an array of objects


   let _products = [

      {

        productID: 680,

        name: "HL Road Frame - Black, 58",

        productNumber: "FR-R92B-58",

        color: "Black",

        standardCost: 1059.31,

        listPrice: 1431.50

      },

      {

        productID: 707,

        name: "Sport-100 Helmet, Red",

        productNumber: "HL-U509-R",

        color: "Red",

        standardCost: 13.08,

        listPrice: 34.99

      },

      {

        productID: 709,

        name: "Mountain Bike Socks, M",

        productNumber: "SO-B909-M",

        color: "White",

        standardCost: 3.3963,

        listPrice: 9.50

      }

    ];


      // Careful with object arrays

      // The array is copied, but the underlying objects are still accessed by reference

      let diff = [..._products];

      diff[0].productID = 999;

      console.log(_products[0].productID);  // 999

      console.log(diff[0].productID);     // 999


Note : objects are not copied by value.objects copied by reference.


ex : concatenate two arrays 


  let _products = [

      {

        productID: 680,

        name: "HL Road Frame - Black, 58",

        productNumber: "FR-R92B-58",

        color: "Black",

        standardCost: 1059.31,

        listPrice: 1431.50

      },

      {

        productID: 707,

        name: "Sport-100 Helmet, Red",

        productNumber: "HL-U509-R",

        color: "Red",

        standardCost: 13.08,

        listPrice: 34.99

      },

      {

        productID: 709,

        name: "Mountain Bike Socks, M",

        productNumber: "SO-B909-M",

        color: "White",

        standardCost: 3.3963,

        listPrice: 9.50

      }

    ];


    let _newProducts = [{

      productID: 712,

      name: "AWC Logo Cap",

      productNumber: "CA-1098",

      color: "Multi",

      standardCost: 6.9223,

      listPrice: 8.99

    },

    {

      productID: 821,

      name: "Touring Front Wheel",

      productNumber: "FW-T905",

      color: "Black",

      standardCost: 96.7964,

      listPrice: 218.01

    }

    ];


     // Concatenation

 

     let allProducts = _products.concat(_newProducts);

      console.log(allProducts.length);                   // 5


      let spProducts = [..._products, ..._newProducts];

      console.log(spProducts.length);                    // 5



Using Spread to pass Parameters to a Constructor


we can also use the spread to help us build objects that, where we pass in multiple

values to the constructor.


ex :


     // Use with 'new'

      let dt = new Date(2019, 10, 15);  // 15 Nov 2019

      console.log(dt);                  // Fri Nov 15 2019 00:00:00 GMT+0530 (India Standard Time)

      

      let dateFields = [2019, 11, 15];  // 15 Dec 2019

      dt = new Date(...dateFields);    

      console.log(dt);                // Sun Dec 15 2019 00:00:00 GMT+0530 (India Standard Time) 


Pass Parameters to a Function :


 ex : using spread for function arguments


    

      let args = [1, 2, 3];

      multipleParams(...args);

  

   function multipleParams(arg1, arg2, arg3) {

      console.log(arg1);

      console.log(arg2);

      console.log(arg3);

      console.log("");

    } 


Output :

1

2

3


Shallow copy on object literals :


The useful feature of the spread operator is used to perform a shallow copy on object literals.


 ex :

   let product = {

        productID: 680,

        name: "HL Road Frame - Black, 58",

        standardCost: 1059.31,

        listPrice: 1431.50

      };


      // The following performs a shallow-copy

      // Similar to Object.assign()

      let prod2 = { ...product };


      // Change the newly copied object

      prod2.productID = 999;


      // Display the objects

      console.log(product);           // {productID: 680, name: "HL Road Frame - Black, 58", standardCost: 1059.31, listPrice: 1431.5}

      console.log(prod2);             // {productID: 999, name: "HL Road Frame - Black, 58", standardCost: 1059.31, listPrice: 1431.5}


      // Display the changed value

      console.log("");

      console.log(product.productID);  // 680

      console.log(prod2.productID);    // 999

 

understanding 'this' in javascript

 


1.Basically 'this' always refers to an object, and that 

object is typically the one in which the current code is running.


2.Sometimes the object can be changed.


1.Using 'this' keyword will have different values based on in which context your code is executing.

2.In a method inside of object : 'this' refers to the owner object.

3.In a function or outside of any function. 'this' refers to the global object.

4.In an event,it's the element that received the event.

5.call()/apply() methods refers to object passed in.

6.'use strict' also affects 'this'.


'this' in Global and Function scope :


ex : without using 'use strict'


   // Global scope - 'this' is mapped to global/window object

    console.log("Begin: global scope sample");

    console.log(this.toString());                                        // [object Window]

    console.log("this === window = " + (this === window).toString());    // this === window = true

    console.log("End: global scope sample");


    // Function scope - 'this' is mapped to global/window object

    // Uncomment 'use strict' above to show how it affects this function

    function functionScope() {   

      console.log(this.toString());                                     // [object Window]

  

      console.log("this === window = " + (this === window).toString()); //  this === window = true

  

    } 


ex : with using 'use strict'


     'use strict'

 

// Global scope - 'this' is mapped to global/window object

    console.log("Begin: global scope sample");

    console.log(this.toString());                                         // [object Window]                          

    console.log("this === window = " + (this === window).toString());     // this === window = true

    console.log("End: global scope sample");


    // Function scope - 'this' is mapped to global/window object

    // Uncomment 'use strict' above to show how it affects this function

    function functionScope() {   

      console.log(this.toString());                                     // Cannot read property 'toString' of undefined           

  

      console.log("this === window = " + (this === window).toString()); 

  

    } 


Note :

 

If you want to get at the global window object when 'use strict' is in effect,

use : console.log(window.toString());


'this' in Event Handlers :


'this' in the context of an event handler always refers to the HTML element to which it's attached.


ex :

  <button onclick="eventHandler(this)">

    Pass to function from event handler

  </button>


// Pass 'this' to function from event handler

    function eventHandler(ctl) {

      console.log(ctl.toString());  // [ object HTMLButtonElement]

    }  


'this' in an Object literal :


'this' inside of an object literal always refers to the properties or a method inside of that object literal.


ex :

   // Object literal

    function objectLiteral() {

      let product = {

        "productID": 680,

        "name": "HL Road Frame - Black, 58",

        "standardCost": 1059.31,

        "listPrice": 1431.50,

        grossProfit: function () {

          return (this.listPrice - this.standardCost)

            .toLocaleString('en-US', {

              style: 'currency', currency: 'USD'

            });

        }

      };


      console.log(product.grossProfit());            // $372.19

    }


'this' with call() and apply() methods :


ex :

    function callAndApply() {

      let product = {

        "productID": 680,

        "name": "HL Road Frame - Black, 58",

        "standardCost": 1059.31,

        "listPrice": 1431.50,

        grossProfit: function () {

          return (this.listPrice - this.standardCost)

            .toLocaleString("en-US", {

              "style": "currency", "currency": "USD"

            });

        }

      };


      let prod2 = {

        "standardCost": 500,

        "listPrice": 850

      }


      // Call using reference to 'product' properties

      console.log(product.grossProfit.call(product));    // $372.19

      // Call using reference to 'prod2' properties

      console.log(product.grossProfit.call(prod2));      // $350.00

      console.log("");

      console.log(product.grossProfit.apply(product));   // $372.19

      console.log(product.grossProfit.apply(prod2));     // $350.00

    }


Note : The call() method takes arguments separately.

The apply() method takes arguments as an array.

A useful mnemonic is " A for array and C for comma".


syntax :

theFunction.apply(valueForThis, arrayOfArgs)

theFunction.call(valueForThis, arg1, arg2, ...)


'this' in constructor Functions :


 ex :

 function Product(id, name, cost, price) {

      this.productID = id;

      this.name = name;

      this.standardCost = cost;

      this.listPrice = price;


      this.grossProfit = function () {

        return (this.listPrice - this.standardCost)

            .toLocaleString("en-US", {

              "style": "currency", "currency": "USD"

            });

      }

    }


      let prod1 = new Product(680, "HL Road Frame - Black, 58", 1059.31, 1431.50);

      let prod2 = new Product(707, "Sport-100 Helmet, Red", 13.08, 34.99);


      console.log(prod1.grossProfit()); //$372.19

      console.log(prod2.grossProfit()); // $21.91

  

Note : we're referencing the different objects, and 'this' then takes on the properties of that object.


Summary :

Scope determines value of 'this' 

 -> Global object

 -> HTML element

 -> Method owner

'use strict' makes 'this' undefined in functions.

what is passed to call()/apply() methods becomes 'this'.

constructor functions owner is 'this'

 

How to Determine javascript variable Data Types

 


Primitive Data Types :


boolean : true or false

null    : no value

undefined : a variable declared, but has no value

number    : integers,decimals,float, etc

string    : a series(array) of characters


Object Data Types :


new Array    : A collection of values

new Error    : contains a name and an error message

new Function : A block of code

new Object   : A wrapper around any type

new RegExp   : A regular expression

new Boolean  : An object that contains true or false

new Number   : An object that contains a numeric value

new String   : An object that contains a character(s)


typeof Operator :


1.Returns the data type of the passed in expression.

2.A string value is returned such as : 'string','number','object', etc.

  

ex : console.log(typeof "Hello"); // 'string'

     console.log(typeof 4);       // 'number'

     console.log(typeof (4*2));   // 'number'


   let _products =[

       {

     productID : 680,

name      : "HL Road Frame - Black, 58",

color     : "Black",

productNumber : "FR-R92B-8",

standardCost  : 1059.31,

listPrice     : 1431.50    

   },

       {

     productID : 707,

name      : "Sport-100 Helmet, Red",

color     : "Black",

productNumber : "UL-R92B-R",

standardCost  : 1059.31,

listPrice     : 1431.50    

   },

       {

     productID : 660,

name      : "HL Road Frame - Red, 56",

color     : "Red",

productNumber : "FR-R92B-8",

standardCost  : 1059.31,

listPrice     : 1431.50    

   }

      ];    


 function typeofSample(){

   let product =_products[0];

   let introDate=new Date();

   let strValue = new String();

   let isActive = false;

   let result;

   let value = null;

   

   console.log("_products = " + typeof _products);                          // object

   console.log("product = " + typeof product);                              // object

   console.log("product.productID = " + typeof product.productID);          // number

   console.log("product.productNumber = " + typeof product.productNumber);  // string

   console.log("strValue = " + typeof strValue);                            // object

   console.log("introDate = " + typeof introDate);                          // object

   console.log(" Result = " + typeof result);                               // undefined

   console.log("isActive = " + typeof isActive);                            // boolean

   console.log("value = " + typeof value);                                  // object

   console.log("typeofSample() = " + typeof typeofSample);                  // function

 

 }

 

 Object Data type / Constructor :

 

1.All object data types inherit from Object (not primitives).

2.Object has a constructor property, and this constructor property returns a reference to the object itself.

3.Object literals and primitives are cast to object for display.



function constructorSample(){


   let product =_products[0];

   let introDate=new Date();

   let strValue = new String();

   let isActive = false;   

   let value = null;

   

   console.log("_products = " + _products.constructor.toString());                          // function Array()         

   console.log("product = " +  product.constructor.toString());                             // function Object()

   console.log("product.productID = " +  product.productID.constructor.toString());         // function Number() 

   console.log("product.productNumber = " +  product.productNumber.constructor.toString()); // function String()

   console.log("strValue = " +  strValue.constructor.toString());                           // function String()

   console.log("introDate = " +  introDate.constructor.toString());                         // function Date()               

   console.log("isActive = " +  isActive.constructor.toString());                           // function Boolean()                           

   console.log("typeofSample() = " + typeofSample.constructor.toString());                  // function Function()

 

 }  


Helper functions for the Constructor property :


ex : 

   let introDate = new Date();

   let result;

   let value = null;

   // use helper functions that return true/false

   

   console.log("_products is Array? = " + isArray(_products));                           // true

   console.log("introDate is Date? = " + isDate(introDate));                             // true

   

   // Be sure to check if something is null prior to using

   console.log("result = " + isNullorUndefined(result)? 'null/undefined': result);       // null/undefined

   console.log("value = " + isNullorUndefined(value)?'null/undefined':value);            // null/undefined


function isArray(value){

  return value.constructor.toString().indexOf("Array")>-1;


function isDate(value){

  return value.constructor.toString().indexOf("Date") >-1;

}


function isNullorUndefined(value){

  return value ===null || value === undefined;

}


The instanceof Operator :


instanceof is different than the typeof because this instanceof 

tests if a specific object inherits from the Object data type (not a primitive).


instanceof tests for a specific type of object or for object itself.


 ex :

 

 // Using the instanceof operator

    function instanceofSample() {

      let prod = new Product(680, "HL Road Frame - Black, 58",

        "FR-R92B-58");

      let dt = new Date();

      let name = new String("Product Name");

      let value = "A simple string";


      console.log("prod instanceof Product = " + (prod instanceof Product).toString());    // prod instanceof Product = true

      console.log("prod instanceof Object = " + (prod instanceof Object).toString());      // prod instanceof Object = true

      console.log("dt instanceof Date = " + (dt instanceof Date).toString());              // dt instanceof Date = true

      console.log("dt instanceof Object = " + (dt instanceof Object).toString());          // dt instanceof Object = true

      console.log("name instanceof String = " + (name instanceof String).toString());      // name instanceof String = true

      console.log("name instanceof Object = " + (name instanceof Object).toString());      // name instanceof Object = true

      console.log("value instanceof String = " + (value instanceof String).toString());    // value instanceof String = false

      console.log("value instanceof Object = " + (value instanceof Object).toString());    // value instanceof Object = false

    }

 

 function Product(id, name, number) {

      this.productID = id;

      this.name = name;

      this.productNumber = number;

      this.color = "Black";

      this.standardCost = 10;

      this.listPrice = 30;

    }


Note : the instanceof only checks for object data types .primitives are not objects.


1. typeof for checking type.

2. instanceof for checking what type of object.  


Note : 

we can use constructor property on both objects and primitives.

Remember that with the primitives, it can actually cast it into an object,

and then we have that constructor property available to us.


Exception handling in Javascript

 1.The try block is where you put code that could fail.

2.An error object is passed to the catch block

3.The code in a finally block always runs


syntax :

         try{

    // some code that could fail

}

catch(error){

    // Do something with the error

}

finally{

    // This code always runs

}


Note : A javascript Error object always has 'name' and 'message' property.


 ex: simple try catch

 

       let result ;

        try{

  result = x / 10;

}catch(error){

  console.log(error.message);  // x is not defined

}


  ex: Finally statement with catch block

    

      let result;

       try{

    console.log("An error will occur.");

result = x / 10;

console.log(" This line will never run.");

   } catch (error){

     console.log(" In the 'catch' block : " + error.message);

   }

       finally{

    console.log("In the 'finally' block ");

   }    


   output : 

        //An error will occur.

        //In the 'catch' block : x is not defined

        //In the 'finally' block 


 ex: Finally statement (Success)

     

         let result;

         let x = 100;

          try{

   console.log("An error won't occur.");

   result = x/10;

  } catch (error){

    console.log("In the 'catch' block : " + error.message);

  } finally{

            console.log("In the 'finally' block");

  } 


   output :

    // An error won't occur.

    // In the 'finally' block   


Throw a Custom Error Object :

1.you can throw your own custom error object.

2.Create an object with at least two properties : "message" and "name".


ex : 


   try{

     attemptDivision();

   }catch (error){

     console.log(error.message + " - Error Type: " + error.name);

   }


   function attemptDivision(){

    let result;

try{

   result = x / 10;

}catch(error){

  // Always include at least a 'message' and 'name' properties

throw{

"message" : "In the attemptDivision() method the following error occurred : " + error.message,

"name"    : "CustomError"  

};

}

   

   }

   

Types of Errors :


1.SynatxError

2.TypeError

3.ReferenceError

4.RangeError

5.URIError

6.EvalError *


ex :

 function referenceError(){

   let result ;

   try{

     // Reference error because 'x' is not defined

result = x/10;

   }catch(error){

     handleError(error);

   }

 }


 function rangeError(){

   let result=0;

   try{

     // Range error because a number cannot have 200 significant digits

result.toPrecision(200);

   } catch (error){

     handleError(error);

   }

 } 

 

 function typeError(){

  let result = 0;

  try{

    // Type error because result is a numeric

result.toUpperCase();

  } catch(error){

    handleError(error);

  }

 

 }

 

 function uriError(){

   let uri = "http://www.netinc.com/path%%%/file name";

   

   try{

    // URI eror

decodeURI(uri);

   } catch (error){

     handleError(error);

   }

 }

 

 function synatxError(){

   try{

   // Syntax error because missing a final single quote

    let sum = eval("alert('Hello)");

   } catch (error){

     handleError(error);

   }

 }

 

 function handleError(error){

   switch(error.name){

    case 'ReferenceError':

console.log("Reference error : " + error.message);

     break;

case 'RangeError':

  console.log("Range error : " + error.message);

      break;

case 'TypeError':

  console.log("Type error : " + error.message);

      break;

case 'URIError':

  console.log("URI  error : " + error.message);

      break;

case 'SynatxError':

  console.log("Syntax  error : " + error.message);

      break; 

    case 'EvalError':

  console.log("Evaluation  error : " + error.message);

      break;

    default :

    console.log("Error Type : " + error.name + " - Message: " + error.message);

break;

   } 

 }


Friday, 18 September 2020

True False values ,Logical Operators and Short-circuit Evaluation in Javascript

 1.Truthy and Falsy values :


In javascript, any variable with a value, such as a string that has characters in it,

a numeric that is non-zero,or a Boolean true is considered true,and you can use it in an 

if statement like that.


Any variable that is a Boolean false,null,undefined,Not a number,or an empty string is considered false.


ex : check for 'truth' values 


     let price =100;

let color = "Red";

 

   // Check if price has something other than zero  

   

if(price){

   console.log("Price is > 0");        // Price is > 0

}

 

 

   // Check if color has characters in it.

   

     if(color){

  console.log("color has a value");    // color has a value

}   


  ex: check for 'false' values 

  

    let color = "Red";

  // Set value to null, it becomes false

    color =null;

    console.log("color == null = " + Boolean(color)); // color == null = false

 

  // Set value to empty string, it becomes false

    color ="";

console.log("color == '' = " + Boolean(color));     // color == '' = false

  // Set value to undefined,it becomes false

   color=undefined;

   console.log(" color == undefined = " + Boolean(color));  // color == undefined = false

   

 // Declare variable and don't initialize, it is false

   let value;

   console.log(" ' let value ' = " + Boolean(value));       // ' let value ' = false

   

  // Result of NaN is false

  value = 100/"test";

  console.log(" 100 / 'test' = " + Boolean(value));        // 100 / 'test' = false

  

2.Logical Operators


Logical AND (&&):

In javascript, the logical AND operator will return true if both operands are true.


When using the AND operator, both sides must return true for the expression to be true.


Logical OR (||):


In javascript, the logical OR operator returns true if either operand is true.


When using the OR opeartor,only one expression needs to be true for the expression to be true;


Logical NOT (!) :


In javascript, the logical NOT operator negate anything




3.short Circuiting :


-> short circuiting is simply an optimization for logical expressions.

-> short circuiting allows javascript to do is to bypass subsequent expressions in And or Or conditions based on truthy or falsy.


ex : short circuiting (&&)


    let result;

// if first result is false, the second part is never evaluated

result = isColorRed("Black") && isGreaterThan1400(1400);  // false

function isColorRed(value){

console.log("In the isColorRed() function");

return value === "Red";

}

    

function isGreaterThan1400(value){

console.log(" In the isGreaterThan1400() function");

return value > 1400;

}

 

  ex : short circuiting (||)

       

   let result;

   

   // Each expression is evaluated until one returns a true

   

   result= isColorRed("Red") || isGreaterThan1400(200);  // true

   

   // In the isColorRed() function

   

   // Each expression is evaluated until one returns a true the rest are then skipped

   

   result = isGreaterThan1400(200) || isColorRed("Black");  // false

   

   // In the isGreaterThan1400() function

       // In the isColorRed() function