Wednesday, 6 April 2016

Using anonymous functions might give problems if used recursively in javascript - an example scenario

Recursive functions in javascript

Making a json object that uses anonymous function instead of a named funciton which causes problem in a scenario in which we make another variable ftn2 to point to the same function ftn by assigning ftn2 to ftn. Then we set ftn to null and we lose our reference to the recrusive call to ftn inside the funciton ftn. If we use a named function then the problem gets solved and recursion works.

// Making a json object that uses anonymous function 
var orgChart = {
    name: 'Dilshad',
    subordinates: [{
        name: 'Rafaqat',
        subordinates: [{
            name: 'Sardar',
            subordinates: []
        }, {
            name: 'Shaukat',
            subordinates: []
        }]
    }]
};
//Writing an anonymous function that uses recursion.
var ftn = function(topEmployee) {
    console.log(topEmployee.name);
    console.log('Number of subordinates of ' + topEmployee.name + ': ' + topEmployee.subordinates.length);
    /* 
      Calling itself recrusively for each employee to check it s(he) has subordinates. 
      */
    for (var i = 0; i < topEmployee.subordinates.length; i++){
     console.log(topEmployee.name + "'s subordinate # " + (i + 1) + ": ");
        //Recursive call to ftn in the line below.
        ftn(topEmployee.subordinates[i]);
    }
};
//calling the funciton ftn and passing it the json object representing the organization chart.
//**********************************
//ftn(orgChart);
//**********************************
/*
Here is the output of the function above:
Dilshad
Number of subordinates of Dilshad: 1
Dilshad's subordinate # 1: 
Rafaqat
Number of subordinates of Rafaqat: 2
Rafaqat's subordinate # 1: 
Sardar
Number of subordinates of Sardar: 0
Rafaqat's subordinate # 2: 
Shaukat
Number of subordinates of Shaukat: 0
*/
//The problem with the anonymous function above starts when we do the following two lines.
//**********************************
//var ftn2 = ftn;
//ftn = null;
//ftn2(orgChart);
//**********************************
/*
We get an error after the first top employee of the organization chart as shown as the recursive call fails because we have set ftn to null and we are still calling it in the recrusive call inside the body of the function. 

Dilshad
Number of subordinates of Dilshad: 1
Dilshad's subordinate # 1: 
Uncaught TypeError: ftn is not a function
*/
/*
 The solution is simple - use a named function instead of an anonymous funciton as shown below:
*/

//Writing a named function that uses recursion.
var ftn = function showAllEmployees(topEmployee) {
    console.log(topEmployee.name);
    console.log('Number of subordinates of ' + topEmployee.name + ': ' + topEmployee.subordinates.length);
    /* 
      Calling itself recrusively for each employee to check it s(he) has subordinates. 
      */
    for (var i = 0; i < topEmployee.subordinates.length; i++){
     console.log(topEmployee.name + "'s subordinate # " + (i + 1) + ": ");
        //Recursive call to ftn in the line below.
        showAllEmployees(topEmployee.subordinates[i]);
    }
};

/* Now the code works even if we do the following. */
var ftn2 = ftn;
ftn = null;
ftn2(orgChart);
/* But don't forget to comment the lines above which were causing errors. The lines between 
//********************************** and //**********************************
 should be commented
*/

Monday, 4 April 2016

Returning a function from another function - closures in javascript

closures are used to persist functions in javascript. It helps us to persist functions and access their context. We can have access to the variables inside the functions even when we are outside the function as the function is not garbage-collected due to persistence.
//closures
var salaryUpdater = function(salary){
 var currentSalary = salary;
  var generator = function(){
   currentSalary *= 2;
    return currentSalary;
  };
  return generator;
};
var updateFtn = salaryUpdater(50000);
console.log(updateFtn());//100000
//*************************************************************
/* 
To prove that the function salaryUpdater and its context is persistent
we will call it twice and will show that the increment made in the
first call remains and the second call increments the salary further. 
*/
var salaryUpdater = function(salary){
 var currentSalary = salary;
  var generator = function(){
   currentSalary += 5000;
    return currentSalary;
  };
  return generator;
};

var updateFtn = salaryUpdater(30000);
updateFtn();
console.log(updateFtn());//40000
//*************************************************************

Indirectly calling functions using the call() and apply() function in javascript

//Using call() and apply() functions
var updateZipCode = function(){
 console.log(this);//Window(....) //this points to the global object Window
};
updateZipCode();
//************************************************************************
var updateZipCode = function(){
 console.log(this);//Object{}
};
/* In the line given below we are passing an empty object as parameter to the call mehtod so that inside the function updateZipCode 'this' can refer to it. */
updateZipCode.call({});
//************************************************************************
var updateZipCode = function(){
 console.log(this);//Object {zip: "22675"}
};
/* In the line given below we are passing an object that has a property zip along with the valu of that property set to 22675 as parameter to the call mehtod so that inside the function updateZipCode 'this' can refer to it. */
updateZipCode.call({zip: '22675'});
//************************************************************************
//We can pass a variable as argument to call() as shown below
var updateZipCode = function(){
 console.log(this);//Object {zip: "24358"}
};
//Making a variable to be passed to the method call() as argument.
var zipCode = {
 zip : '24358'
};
updateZipCode.call(zipCode);
//************************************************************************
//Using a function that requires arguments. 
var updateZipCode = function (newZip, country) {
 console.log(newZip + ' ' + country);//98679 japan
};
var zipCode = {
 zip: '45345'
};
/*In the line below we are passing the object zipCode as the first argument which will be associated with the keyword 'this' in the function updateZipCode(). We are also passing the arguments for the neqZip and country.
*/
updateZipCode.call(zipCode, '98679', 'japan');
//************************************************************************
/* The apply() function gets an array as argument and break down this array 
in to arguments to pass them to the function updateZipCode(). If we supply 
a list of arguments instead of an array it will not work. */
var updateZipCode = function(newZip, country){
 console.log(newZip + ' ' + country);//29468 japan
};
var zipCode = {
 zip: '34679'
};
updateZipCode.apply(zipCode, ['29468', 'japan']);
/*
If we use apply() but instead of an array, pass it a list then we get the 
following error:
Uncaught TypeError: CreateListFromArrayLike called on non-object
*/
//updateZipCode.apply(zipCode, '29468', 'japan');
//************************************************************************

'this' keyword in functions and the global space - an exercise on what 'this' refers to in a piece of code

//This file explains the this keyword in functions and the global space but does not explain the use of this in eventhandlers.
console.log(typeof this);//object
console.log(this === window);/*true. It refers to the window object. Will not works in node as node doesn't have a window object as it works on a server.*/
var name = 'Dilshad';
console.log(this.name);//result ???
console.log(name);//Dilshad
//"this" gets assigned to window if we specify it in the global space without attaching it to any object.
var updateSalary = function(){
 console.log(this === window);//true
};
updateSalary();
//**************************************************************************************************
var employee = {
 name: 'Jeff',
  updateSalary : function (){
   console.log(this);
    /* 
    Object {name: "Jeff"} shows that 'this' refers to the object employee as function updateSalary() is attached to an object    employee.
    */
  }
};
employee.updateSalary();
//**************************************************************************************************
var employee = {
 name: 'Dilshad',
  updateSalary: function() {
   var fn = function () {
     console.log(this);/* Window {external: Object, chrome: Object, document: document, speechSynthesis: SpeechSynthesis, caches: CacheStorage…}  shows that keyword 'this' is attached to the global window. as function window has no object attached to it and 
      therefore the keyword this gets attached to the window. We can ascertain it by using the following line also.*/
      console.log(this === window);
    };
    fn();
  }
};
employee.updateSalary();
//**************************************************************************************************
//We have a constructor function given below 
var Address = function (line1) {
 this.line1 = line1;
  console.log(this);//Address {line1: "Chak 79 Street 12"}
};
/* Creating a new object using the operator 'new' and calling the constructor and passing it a string. 
This will attach the keyword 'this' to this newly created object. */
var address = new Address('Chak 79 Street 12');
//**************************************************************************************************
var Address = function (line1){
 this.line1 = line1;
};
/* Creating a function and attaching it to the prototype of the constructor so that all
instances created by this constructor can have access to the function to update zip codes
in the instance that call this function.*/
Address.prototype.updateZipCode = function(){
 //update the zipcode here in the address object created by the constructor Address
  console.log(this);//Address {line1: "chak 79 Street 12"}
};
//creating a new instance/object address
var address = new Address('chak 79 Street 12');
address.updateZipCode();
//**************************************************************************************************

//**************************************************************************************************

Sunday, 3 April 2016

Constructor functions and their empty prototypes and adding functions to those prototypes in javascript

/* 
Finding the type of Object in js. Object is of type function in js and not of type Object. 
Object is a constructor function in js. 
*/
console.log(typeof Object);//function
//****************************************************************************************
var Employee = function (name, boss) {
 this.name = name;
  this.boss = boss;
};
var newEmployee = new Employee('jj', 'jhon jhones');
console.log(typeof newEmployee);//object
console.log(newEmployee.name);//jj
console.log(newEmployee.boss);//jhon jhones
//****************************************************************************************
var Employee = function(name){
 this.name = name;
};
var e1 = new Employee('jj');
var e2 = new Employee('kk');
var e3 = e1;
console.log(e1 == e2);//false
console.log( e1 === e2);//false
console.log(e1 == e3);//true
console.log( e1 === e3);//true
//****************************************************************************************
//__ double underscore is called dunder proto and is a kind of hack to enable us to reach the prototype 
console.log(e1.__proto__ === e2.__proto__);//true
/* The line above proves that both the employee objects have the same prototype and that
makes it very easy for the programmer to add functionalities to the Employee. We don't have
to write a function for the thousand of employee objects instead we just write it once
in the prototype of our Employee and all ojbects have acess to it.
*/
//****************************************************************************************
/* We should not add function to the body of the constructor Employee otherwise it would 
be duplicated into the body of all those objects that we are creating using this 
constructor. The following block of code is wrong. */
var Employee = function (name){
 this.name = name;
  this.giveRaise = function(){
   //Increase the salary by 10 %.
  };
};
var e1 = new Employee('jj');
var e2 = new Employee('kk');
console.log(e1.giveRaise === e2.giveRaise);//false
/* The line above gives false as both e1 and e2 get their own copies of function giveRaise() when
they are created using the constructor Employee. *
/* The correct way to do it is to add the function giveRaise to the prototype of the Employee constructor. See later in the code. */
//****************************************************************************************
/* When we work with json objects, we do not have direct access to the prototypes but 
now when we are working with the Constructor functions we do have access to the prototype. */
console.log(typeof Employee.prototype);//object
//****************************************************************************************
//Is Employee.prototype is the same as Object.prototype?
console.log(Employee.prototype === Object.prototype);//false
/* The line above gives false and that proves that Employee has got its own empty prototype
object. In json, each object has its prototype set to Object.prototype but that is not
the case when we are dealing with constructor functions. */
//****************************************************************************************
/* The correct way to add a funciton is not to add it to body of the constructor Employee
as done above in the code but to add it to the prototype of the connstructor Employee as 
shown below: */
var Employee = function (name){
 this.name = name;
  this.salary = 25000;//All employees get a start salary of 25 k during creation of an object of type Employee
};
Employee.prototype.giveRaise = function(raise){
 this.salary += raise;
};
var e1 = new Employee('jj');
var e2 = new Employee('kk');
console.log(e1.giveRaise === e2.giveRaise);//true
/* Now even if we 50 k employees we don't duplicate the function as we have added it to the  
prototype of the constructor function and all the employees objects can call it. */
e1.giveRaise(5000);
console.log(e1.salary);
console.log(e2.salary);
//****************************************************************************************

Defining custom properties on an object to have more control.

'use strict';
//We define an empty object.
var task = {};
//We define a property on the object task with key as 'text' and value as 'Get this job done!'
Object.defineProperty(task, 'text', {
 value: 'Get this job done!'
});
console.log(task.text);
//*****************************************************************
var task = {};
Object.defineProperty(task, 'text', {
 value: 'Get this job done!',
  //By default writable : false. Therfore, we have to set it to true if want o make th property text writable
  writable: true
});
/* 
If the writable : true is commented out then by default writable : false and we will get TypeError: can not assign to read only property.
*/
task.text = task.text + ' ... Now!';
console.log(task.text);
//*****************************************************************
var task = {};
Object.defineProperty(task, 'text', 
{
 value: 'Get this job done!',
  //enumerable is used in for in statements
  enumerable: true
});
for(var f in task){
 console.log(f);/* We get text on the console but if we do not set enumerable: false then by default 
  enumberable: false and nothing will be shown on the console.*/
}
//*****************************************************************
var task = {};
Object.defineProperty(task, 'text', {
 value: 'Get this job done!',
  configurable: true
});
Object.defineProperty(task, 'text', {
 value: 'Done!'
});
console.log(task.text);/* The output on the console is 'Done!' as configurable: true but if we set
configurable: false or just delete that line then by default configurable:false and, therefore, we get
Ucaught TypeError: Cannot redefine property: text 
*/
//*****************************************************************
//Getter functions
var task = {
 _dueDate: '1/30/2016'
};
Object.defineProperty(task, 'dueDate', {
 get: function(){
   return this._dueDate;
  }
});
console.log(task.dueDate);
//*****************************************************************
//Setter function
var task = {
 _dueDate: '1/30/2016'
};
Object.defineProperty(task, 'dueDate', {
 get: function (){
   return this._dueDate;
  },
  set: function (newValue) {
   this._dueDate = newValue;
  }
});
//The line below will call the setter funciton 
task.dueDate = '10/28/2016';
console.log(task.dueDate);
//*****************************************************************
//Assigning multiple properties to a single task
var task = {};
Object.defineProperties(task, 
 {
   // Setting the property text of the object task
  'text': {
    value: 'New Task'
   },
    //setting the property dueDate of the object task
   'dueDate': {
    value: '1/30/2014'
   }
 }
);
console.log(task.text + ' Due: ' + task.dueDate);
var descriptor = Object.getOwnPropertyDescriptor(task, 'text');
console.log(descriptor);//Object {value: "New Task", writable: false, enumerable: false, configurable: false}
var descriptor = Object.getOwnPropertyDescriptor(task, 'dueDate');
console.log(descriptor);//Object {value: "1/30/2014", writable: false, enumerable: false, configurable: false}
//*****************************************************************

//*****************************************************************

Wednesday, 30 March 2016

Some features of arrays in java script

Some features of Arrays in java script

var entries = new Array('Trains', 'Planes', 'Automobiles', 'Carts');
console.log(entries instanceof Array);
console.log(entries);
//You can leave out the new keyword and it still works
var entries = Array("Ajmal", "Dilshad", "Russell", "Anders");
console.log(entries instanceof Array);
console.log(entries);
//We can make array with [] also.
var places = ['Malmö', 'Lund', 'Stockholm', 'Gothenborg'];
console.log(places instanceof Array);
console.log(places);
console.log(places[1]);
//No exception gets thrown if you access a non-existing index
console.log(places[9]);//Get undefined.
//Initializing array of a particular length
var books = new Array(5);
console.log(books.length);//returns 5
var books = new Array("5");//one string element. Not length.
console.log(books.length);
var entries = [,,,];
console.log(entries.length);

//We can assign a numeric length to the length property of an array
var transport = ['Planes', 'Trains', 'Carts', 'Buses'];
console.log(transport.length);
transport.length = 10;
console.log(transport.length);
transport.length = 2;
//Accessing a non-existent index of the array gives undefined.
console.log(transport[3]);
//Assigning a new means of transport to a non-existing index.
transport[49] = 'Cars';//expands the array.
console.log(transport[49]);
console.log(transport.length);
//Appending to the end of the array
transport[transport.length] = 'Bicycles';
console.log(transport.length);

//To get a comma separated list of the elements of an array
console.log(transport.toString());

var ratings = [5, 2, 4];
console.log(ratings);
console.log(ratings.valueOf());

//For separating the elements of the array with another string
console.log(ratings.join('|'));
console.log(ratings.join('   '));

//Array acting as a stack.
var ratings = [];
ratings.push(5);
ratings.push(2, 4);
console.log(ratings.length);
ratings.shift(1);
console.log(ratings.length);
//To check that the element at index 0 does not exit now.
console.log(ratings.valueOf());
console.log(ratings.pop());//Gets us the last inserted element
console.log(ratings.length);
//Inserting a new element at the beginning
ratings.unshift(9);
console.log(ratings.valueOf());
ratings.unshift(8);
console.log(ratings[0]);
console.log(ratings.valueOf());
var newCount = ratings.unshift(7);
console.log(ratings.valueOf());
console.log(newCount);

//Concatenation on arrays
var ratings = [1, 2, 3];
var newRatings = ratings.concat([4, 5, 6]);
console.log(newRatings.length);
console.log(newRatings.valueOf());
newRatings = newRatings.concat([7, 8], 9, 10);
console.log(newRatings.valueOf());

//Slicing an array to get the remaining element
var ratings = [1, 2, 3, 4, 5, 6, 7];
var newRatings = ratings.slice(2);//2 means index 2 
console.log(newRatings.valueOf());
console.log(newRatings.toString());
var newRatings = ratings.slice(1, 4);//Gives 2,3. Excludes index 3
console.log(newRatings.toString());
console.log(newRatings.valueOf());
//Passing a negative argument to slice function give elements from the end of the array
var newRatings = ratings.slice(-2);
console.log(newRatings.valueOf());

//Starting at ith index and deleting x number of elements
var ratings = [1, 2, 3, 4];
ratings.splice(1, 2);//Start from index 1 and delete 2 items.
console.log(ratings.toString());//The riginal array gets modified.
//Getting the removed elements as an array with splice function
var ratings = [1, 2, 3, 4];
var removedRatings = ratings.splice(0, 2);
console.log(removedRatings.toString());
console.log(ratings.toString());

//Function splice with three arguments.
var ratings = [1, 2, 3, 4];
//start at index 2, delete nothing and insert 99 at index 2
ratings.splice(2, 0, 99);
console.log(ratings.toString());
//We can insert more than one items also
var ratings = [1, 2, 3, 4];
ratings.splice(2, 0, 99, 100, 101);
console.log(ratings.toString());
//We can delete items and insert items at the same time
var ratings = [1, 2, 3, 4];
//Start at index 2, delete one item and insert 3 items.
ratings.splice(2, 1, 99, 200, 300);
console.log(ratings.toString());

//Reversing elements of an array
var ratings = [1, 2, 3, 4,];
ratings.reverse();
console.log(ratings);

//Sorting the elments of an array that is not the correct way
//The sort function is treating elements liks Strings while sorting
var ratings = [1, 4, 10, 14,];
ratings.sort();
console.log(ratings.toString());
//The correct way to use function is sort is to pass it a function
var ratings = [1, 4, 10, 14,];
ratings.sort(
       function(value1, value2){
               return value1 - value2;
              }
            );
console.log(ratings.toString());

//Searching an item in an  array
var ratings = [1, 2, 3, 4, 5, 4, 3, 2, 1];
console.log(ratings.indexOf(3));//returns 2
console.log(ratings.indexOf('3')); //returns -1 as it can not find '3' in the array
console.log(ratings.indexOf(66));//returns -1 as there is no 66 in the array.
var names = new Array("Ajmal", "Dilshad", "Russell", "Anders", "Russell");
console.log(names.indexOf("Dilshad"));
//lastIndexOf() function starts at the end of the array to search
console.log(names.lastIndexOf("Russell"));