Saturday 9 April 2016

The strict mode in javascript

//strict mode in js
var actNow = function(){
 'use strict';
    newVariable = 9;
};
actNow();/* Uncaught ReferenceError: newVariable is not defined. */
/* Due to strict mode we have to define the variable newVariable with keyword var as the strict mode will not allow us to place the variable in the global scope. */
/* If you use 'use strict' mode in the global space while using thir party libraries you may face problems if the those libraries are not meant to be used in the strict mode. */

//*******************************************************
var actNow = function(){
 //'use strict';
    newVariable = 9;
};
actNow();
/* Here we have commented the line with the strict mode so we get no error from this snippet and the variable will be placed in the global space. */

//*******************************************************
//The 'delete' operator removes a variable from the context
var actNow = function(){
 var newVar = 9;
    delete newVar;
};
actNow();//No error and the code works.
//*******************************************************
//The 'delete' operator is not allowed in the strict mode.
var actNow = function(){
 'use strict';
 var newVar = 9;
    delete newVar;
};
actNow();/* Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. */
/* If we declare a variable in strict mode, we can't get rid of it. */
//*******************************************************
/* The following code gives no error as we are not in strict mode inspite of the fact that both the arguments have the same name.
*/
var actNow = function(){
    var fn = function(x, x){
     //Do something here.
    };
};
actNow();//no error

//*******************************************************
var actNow = function(){
 'use strict'
    var fn = function(x, x){
     //Do something here.
    };
};
actNow();
/* Uncaught SyntaxError: Duplicate parameter name not allowed in this context */
//*******************************************************
'use strict';
var obj ={};
with(obj){
 console.log('using with statement');
};
//*******************************************************

Friday 8 April 2016

Some global functions in javascript

Some global functions in javascript


var value = parseInt('1234');
console.log(value);
var value = parseInt('b1234');
console.log(value);
var value = parseInt('12b34');
console.log(value);//When a NaN is hit it stops further parsing but 12 is shown on the console
var value = parseInt('1234.9');
console.log(value);//1234 - It ends parsing when it hits the decimal point. Doesn't do rounding for us.
var value = parseInt('C000', 16);//16 is the base/radix so c000 is a hexadecimal number.
console.log(value);

var value = parseFloat('1234.999');
console.log(value);//1234.99
//Parsing the float with exponential number.
//Move the decimal to one place to the left
var value = parseFloat('1234e-1');
console.log(value);//123.4

var value = isFinite(Number.POSITIVE_INFINITY);
console.log(value);//false

var value = isFinite(Number.NEGATIVE_INFINITY);
console.log(value);//false

var value = isFinite(42);
console.log(value);//true

var value = isFinite('42');
console.log(value);//true

var value = isNaN(NaN);
console.log(value);//true

var value = isNaN(3 / 0);
console.log(value);/* false because isNaN(infinity) is false. Most of the other programming languages will give an exception when dividing a number by zero but js does not give exception. */

var value = isNaN(Number.POSITIVE_INFINITY);
console.log(value);//false

var value = isNaN(Number.NEGATIVE_INFINITY);
console.log(value);//false

var value = isFinite( 3 / 0);
console.log(value);//false because 3 / 0 gives infinity

var path = "\\start\\";
console.log(encodeURI(path));//%5Cstart%5C

var path = "\\start\\+";
console.log(path);//\start\+
var path = "\start\+";
console.log(decodeURI(path));//start+

var path = "\\start\\";
console.log(encodeURIComponent(path));//%5Cstart%5C

var path = "\\start\\+";
console.log(encodeURIComponent(path));//%5Cstart%5C%2B
var path = "%5Cstart%5C%2B";
console.log(decodeURIComponent(path));//\start\+

/* The following global function should be avoided as it opens systems to injection attack and other attacks. */
var globalVar = 'qwerty';
var code = 'console.log(globalVar);';
eval(code);

The Math object in javascript - some important functions

The Math object in javascript - some important functions


//Math object in js
console.log(Math.PI);
console.log(Math.abs(-36));
console.log(Math.ceil(23.12));//24
console.log(Math.floor(23.99));//23
console.log(Math.trunc(34.67));//34
console.log(Math.max(0,67,-3,"99"));//99 the string is converted implicitly to a number
console.log(Math.min(-23, 0,56));
console.log(Math.pow(3,4));//81
console.log(Math.random());//between 0 and 1
console.log(Math.sqrt(64));
console.log(Math.sqrt(-64));//NaN

the string object in javascript - some important functions

The string object in javascript - some important functions


//Some important functions in the string object in js
var value = 'Some string';
console.log(value.charAt(6));//t
console.log(value.concat(' concatenated with this one.'));
console.log(value.includes(' '));
console.log(value.endsWith('ing'));
console.log(value.endsWith('ing '));/* false - There is a space at the end which is not trimmed by function endsWith() */
console.log(value.indexOf('r'));
console.log(value.indexOf('Z'));//-1 as Z is not found in the string value
console.log(value.lastIndexOf('s'));//starts at the end of the string and goes backwards
console.log(value.slice(5));//string - start at index 5 and return a slice of the original string
console.log(value.slice(5, 8));//str - start at index 5 and returna slice up to but not including index 8
//Give me the final 3 characters starting from the end of the string
console.log(value.slice(-3)); // - ing - negative argument shows starting backwards.

//Splitting a string into an array
var str = "This is a string that we will split into an array on the basis of a space character and has 22 words.";
console.log(str.split(' ').length);//22 because we are splitting using a space and that makes it 22 elements
console.log(str.substr(40, 9));//an array - start at index 40 and return 8 characters.

/* If you want a string that starts at index i and ends at index j but j is not included then use str.substring(i, j) function instead of substr(beginningIndex, numberOfCharactersToReturn) function.
*/
console.log(str.substring(40, 65));//character at 65 is not included.

Event bubbling in javascript

Event bubbling and capturing

Event bubbling and capturing are two ways of event propagation in the HTML DOM API, when an event occurs in an element inside another element, and both elements have registered a handle for that event. The event propagation mode determines in which order the elements receive the event.
With bubbling, the event is first captured and handled by the innermost element and then propagated to outer elements.
With capturing, the event is first captured by the outermost element and propagated to the inner elements.
Capturing is also called "trickling", which helps remember the propagation order:
trickle down, bubble up
Back in the old days, Netscape advocated event capturing, while Microsoft promoted event bubbling. Both are part of the W3C Document Object Model Events standard (2000).

Here is the html:

<div id="div1" class="element1">The blue square <div id="div2" class="element2"> The red square </div> </div>

Here is the css:

.element1{
  background-color: blue;
  height: 200px;
  width: 200px;
  position: relative;
  top: 2px;
  left: 20px;
}
.element2{
  background-color: red;
  height: 100px;
  width: 100px;
  position: relative;
  top: 40px;
  left: 50px;
}

Here is the javascript:

/* Event bubbling. */
/* The html used in this js file is given in the html file. */
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
var clickHandler = function divClickHandler(event){
console.log(this.id);
};
div1.addEventListener('click', clickHandler, false);//bubbling
div2.addEventListener('click', clickHandler, false);//bubbling
/* 
The false as the thrid argument in the method call above causes the bubbling. First event is handled
by div2 and then it it is bubbled to its parent div1. If we want it the other way round i.e., we wnat div1
 to handle the event first and then bubble it to div2 then we need to set the boolean value to true as the
 thrid argument in the call to addEventListener().
 */
div1.addEventListener('click', clickHandler, true);//capturing
div2.addEventListener('click', clickHandler, true);//capturing

/* If we wnat the event to be handled by the parent but not by the child then we can stop the propagation of 
the event by using method stopPropgagation() as shown below. In this case the parent will handle the event 
and stop further propagation of the event to the child. 
*/
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
var clickHandler = function divClickHandler(event){
console.log(this.id);
    event.stopPropagation();
    /* 
    If we want to prevent the default action when something is clicked then we include the followin one line of   code also. 
    */
    event.preventDefault();
};
div1.addEventListener('click', clickHandler, true);//capturing
div2.addEventListener('click', clickHandler, true);//capturing

Thursday 7 April 2016

The Event Object in javascript


The event object in javascript is created by the javascript runtime engine which gets passed to an event handler. Here are some key properties of this object:

1. bubbles - true or false - based upon whether this event bubbles up to their parents or not.

2. cancelable - true or false - will let us know whether we can cancel any kind of propagation of this event.

3. currentTarget - is the DOM (Document Object Model) element that we are currently looking at.

4. defaultPrevented - true or false - tells us if preventDefault() was called.

5. detail - This property holds extra information about the event.

6. eventPhase - 1/2/3 - 1 means that it is the capture phase which is the opposite of bubbling - going in the other direction of bubbling. 2 means that we are currently at the target. 3 means that we are in the process of bubbling.

7. preventDefault() - To prevent the browser from executing any default behavior. An example would be preventing the submit button on a form submit the form. Another example would be preventing the browser following a link in an anchor tag.

8. stopPropagation() - will stop all event-capturing and bubbling.

9. stopImmediatePropagation - will stop all event-capturing and bubbling but will also make sure that no more handlers get called.

10. target - the original target of this event. For example if we click on a button and the event bubbles up from parent to parent to parent, target will be set to that original button.

11. trusted - true or false - true if event comes from the browser. false if event is triggered through the javascript code written by the programmer.

12. type - name of the event. For example it would be the string "click" for a click event.

Query selectors in javascript

Here is the html code that will be used in the javascript on this page.

<article id="article1" class="my-custom-class">
    <h3>
        Title of the page goes here.
    </h3>
    <p>
        This is paragraph one.
    </p>
    <p class="special">
        This is paragraph two.
    </p>
    <p class="special">
        This is paragraph three.
    </p>
</article>

Here is the javascript code that uses the html code above.

//Query selectors
/* 
Use MDN, the Mozilla Developers Network to learn more about other functions and properties.
 */
var element = document.querySelector('article');
console.log(element);//prints on the console the complete article tag
var element = document.querySelector('#article1');
console.log(element);
//Getting only the first paragraph
var element = document.querySelector('.special');
console.log(element);
//Getting all the paragraphs in the document
var elements = document.querySelectorAll('.special');
console.log(elements);

Document object in javascript - introduction

Here is the html code that has been used in the javascript code on this page.

<article id="article1" class="my_new_class">
    <h3>
        Demonstrating how to get an element fron an html document in javascript
    </h3>
    <p>
        This is paragraph one.
    </p>
    <p>
        This is paragraph two.
    </p>
    <p class="new_point">
        This is paragraph three.
    </p>
    <p class="new_point">
        This is paragraph four.
    </p>
</article>

Here is the javascript code that uses the html code above.

var element = document.getElementById('article1');
console.log(element);//We get the element in the document that has id=article1
var elements = document.getElementsByTagName('p');
console.log(elements);//We get an array of all the elements that has a tag of p i.e., paragraph
var element = document.getElementsByTagName('h3');
console.log(element);//We get an array of all the elements with heading set to h3
var elements = document.getElementsByClassName('new_point');
console.log(elements);//We get an array of our two paragraph elements with class=new_point

//***************************************************************************
/* 
Once we get an element from a document then we can get access to any of its attributes also. 
*/
var e = document.getElementById('article1');
console.log(e.getAttribute('class'));//my_new_class

//We can dynamically set an attribute also. 
e.setAttribute('class', 'my_old_class');
console.log(e.getAttribute('class'));//my_old_class

//We can get all the child nodes of an element.
console.log(e.childNodes); /* We get on the console
[text, h3, text, p, text, p, text, p.new_point, text, p.new_point, text]
the array has text 6 times because we have spaces before the h3, and all the paragraph elements and white space is represented as text. */

The location object in javascript

/* 
The location object lets us look at the browser's URL location. 
*/

console.log(location.href); // https://fiddle.jshell.net/_display/

console.log(location.host); //fiddle.jshell.net

console.log(location.port); //port number

console.log(location.protocol); // https:


//redirecting to another page/website but it depends on your browsing settings.
location.assign('https://www.google.com');//directs browser tot he page passed as argument.

System Dialogs in javascript - alert, confirm, and prompt

//System dialogs
//1. alert
alert('Hello jsfiddle.net');


//2. confirm - with ok and cancel button ok button for the if is true case and cancel button for the else case 
if(confirm('Do you want to leave this page?')){
 console.log('You chose to leave the page.');
}
else{
 console.log('You chose to stay on the page.');
}

//3. prompt - with an ok and a cancel button
var input = prompt('Enter Your address please!');
if(input != null && input != '')
 console.log(input);
else
{
 console.log('You did not enter any address');
}

timer in javascript

//Timer related code snippets in js
console.log(new Date().getSeconds()); //e.g., 49 seconds
/* function setTimeout() is a global object window and we do not need to prefix it with window.*/
setTimeout(function() {
  console.log(new Date().getSeconds());
 }, 1000
);/* 1000 milliseconds of delay should be observed before calling the function setTimeout after the internal function has been called. */
/* I got 
6
7
because there were 6 seconds in to the minute and then it was 7 seconds into the minute. Note that the 7 appears after an 
interval of 1 second after the 6 appears on the console. If I delete the ', 1000' then I will 
instead get
6
6
as no delay is being observed. 
*/

//*******************************************************
console.log(new Date().getSeconds());
/* Assigning the id of the timer to a variable so that we use that id later on to clear the timer and prevent it from being activated. */
var id = setTimeout(function(){
  console.log(new Date().getSeconds());
 }, 1000
);
clearTimeout(id);
/* After executing the code above we get only one number as our timer is prevented being activated by the clearTimeout() method.
*/
//*******************************************************
/* In the code snippet given below we pass a funciton to method setInterval() and that internal function will be called over and 
over again untill the if condition is true and it is then when the function clearInterval(id) will be called to stop calling the 
internal function.
*/
console.log(new Date().getSeconds());
var id = setInterval(function(){
  var seconds = new Date().getSeconds();
        console.log(seconds);
        if(seconds === 30)//shutting down the timer when there are 30 seconds into the minute
         clearInterval(id);//id exists in the outer function.
 }, 1000
);
//*******************************************************


Window object in javascript

console.log(window.screenLeft + ', ' + window.screenTop);//0,0 but depends on where the window is positioned on your screen
/* innerWidth is where your html document is showing. The brower ususall has some kind of frame and that is included in the outer width. */
console.log(window.innerWidth + ', ' + window.outerWidth);//100, 1280 
window.open('http://www.google.com', '_blank');/*Popup might be blocked so you will not get a new window but might get an indication that a poping up window has been blocked.*/

Recursive functions in javacript - an introduction

//Recursion in javascript 
//functions
/* 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. 
*/
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
*/



Here is the output on the console:

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

Immediately invoked function expressions (IIFEs)

//IIFEs - Immediately invoked function expressions
//IIFEs don't pollute the global environment.
(function(){
 console.log('Executed!');
})();
//*************************************************************
/* We can move the last pair of parenthesis () before the semicolon inside the parenthesis containing hte whole function. This works the same way as the
code snippet given above. 
*/
(function(){
 console.log('Executed again!');
}());
//*************************************************************
//IIFEs don't pollute the global environment.
(function(){
 var employeeName = 'Jack';
})();
/* The linew of code below will give error as employeeName has been declared
with keyword var inside the function so it does not pollute the global 
namespace. Its scope is limited to the function only. */

/* console.log(employeeName);//Uncaught ReferenceError: employeeName is not defined
*/
//*************************************************************
/* app in the code below is an object that is empty here but in a real
app it will be populated. Most of the libraries in js has
a global variable e.g., $ in jQuery. An application has often a variable
in the global namespace called app. */
var app = {};
(function (ns) {
 ns.name = 'None';
})(app);//Passing the global variable app as an argument to the IIFE function.
console.log(app.name);//None
//*************************************************************
var app = {};
var jQuery = {};
/* The way we pass jQuery as a second argument to the IIFE guarantees that
the jQuery === $ (the dollar sign). */
(function (ns, $) {
 ns.name = 'None';
  console.log($ === jQuery);//true
})(app, jQuery);
//*************************************************************
/* To make sure that the system's undefined object is set to the undefined 
object we do as given below: */
var app = {};
var jQuery = {};
(function (ns, $, undefined) {
 ns.name = 'None';
  console.log(undefined);//undefined
})(app, jQuery);
//*************************************************************
//We can also use +, -, or ! with the keyword function instead of parentheses
+function(){
 var employeeName = 'Jack';
  console.log('Executed!');//Executed
}();
console.log(employeeName);//Uncaught ReferenceError: employeeName is not defined.
//*************************************************************

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}
//*****************************************************************

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