Advanced Javascript in 60 minutes
Advanced Javascript in 60 minutes
Hemanthkumar and Abdul Rahman
Buy on Leanpub

Preface

Javascript is becoming most widely used programming languages. In the streams like web development, server side, game development, embedded system etc. Many people try to understand the features and capability that this language provides. But there is more to it than just understanding the stuffs.

Many people try to understand what we can do with this language. But most of us don’t know the fact that what this language itself can do and capable of. This book try to bridge that gap with less and simple words and minimal pages.

This book is designed in such a way that you can not only get the grasp of the advanced features, but also to understand it in minimal time.

Who this book is for

This book is for the intermediate and advanced beginners, you know how to accomplish the basic things in javascript, but no idea what is really going on and want to dive deeper with no time.

This book is for you.

Structure of this book

This book is structured in many chapter, In the way we started out journey to the world of advanced javascript. All the concepts are explained in simple and minimal words. so that you can get a grasp of all the advanced features in 60 minutes.

Let’s begin

1.The Object

Introduction

As an intermediate javascript developer you might already know what object in javascript means, but it is best to start with little basic. To be exact, an Object is simply the collection of key value pair, the key is called property and value holds other javascript object or primitive typed value.

1 var obj = {
2     property1: 1,             //Primitive typed value
3     property2:{},             //Object as value
4     property3:function(){},   //Function object as value
5     .....
6 };

In addition to this, javascript is equipped with its own build in standard objects like Object, Function, null, undefined, Date, Number, String, etc. Click here for the complete listing.

Enough of basics, let dive into the core !

Built in properties

Every javascript object has build in properties we will be covering some the them, they are

  • constructor
  • hasOwnProperty
  • isPrototypeOf
  • propertyIsEnumerable

You won’t be using most of these in your day to day life, but learning these will be helpful when you do some deep stuffs. so lets begin.

constructor

Usually this property hold the reference to the function object which is the creator of that object. for example Lets say an object is created by the function.

1 function foo()
2 {
3 }
4 
5 var obj=new foo();
6 console.log(obj.constructor==foo);    //Result:true

Here the constructor property holds the reference to the function foo which is the creator of the object. Similarly when an object is created

1 var obj = {};
2 //This is equivalent to
3 //var obj=new Object();
4 
5 console.log(obj.constructor==Object)  //Result:true

hasOwnProperty

This is a function in object which is used to test whether a specific property is there in the object or not. There are traditional ways available to do that but what difference does this function make ?. Lets consider an object

1 var A={
2   property1:1,
3 };
4 
5 console.log(A.property1!==undefined);      //Result : true
6 console.log(A.hasOwnProperty('property1')); //Result : true

Both the methods are used to test whether the property is there in the object or not, Now consider the below scenario

1 var B={
2 }.prototype={
3   property1:1,
4 };
5 
6 console.log(B.property1!==undefined);       //Result : true
7 console.log(B.hasOwnProperty('property1')); //Result : false

hasOwnProperty return false since the property1 is not direct property of object B and it is linked through prototype chaining. During for-in loop iterations this function is used in order to prevent iterating the properties belong to prototype chaining.

isPrototypeOf

This is a function which is used to check whether an object is in prototype chain of the current object. For example consider the following piece of code.

1 var A={};
2 var B=Object.create(A);     //B is now in prototype chain of A.
3 
4 A.isPrototypeOf(B);         //Return true.

Object B is created with A as prototype, Since B is in prototype chain of A, isPrototypeOf returns true. We will be covering the prototype property in the later chapter.

propertyIsEnumerable

When ever you define a property for an object it is enumerable in for-in loop.

 1 var A={
 2   property1:1,
 3   property2:2
 4 }
 5 
 6 for(var index in A)
 7 {
 8   console.log(index);
 9 }
10 
11 //Result:
12 //property1
13 //property2
14 
15 A.propertyIsEnumerable('property1');    //return true
16 A.propertyIsEnumerable('property2');    //return true

But there is a way to define property which is non enumerable through for-in loop.

 1 var B={
 2   property1:1,
 3 }
 4 
 5 //defining property2 as non-enumerable
 6 Object.defineProperty(obj, "property2", { value: 2, enumerable: false });
 7 
 8 for(var index in A)
 9 {
10   console.log(index);
11 }
12 
13 //Result:
14 //property1
15 
16 B.propertyIsEnumerable('property1');    //return true
17 B.propertyIsEnumerable('property2');    //return false

In the above example property2 is non-enumerable and wont be visible in for-in loop.

Pass by reference

In Javascript, by default object are pass by reference in nature, for example

 1 var A={
 2     value:1
 3 };
 4 
 5 function foo(obj)
 6 {
 7     obj.value++;
 8 }
 9 
10 console.log(A.value);     //result:1
11 foo(A);
12 console.log(A.value);     //result:2

As you see the object A is passed to function foo and the changes done in that object is actually reflecting in the object A since it is pass by reference.

undefined and null

As a javascript developer you already came across these strange thing called undefined and null. But what is the exact difference.Lets consider an example.

1 alert(undefine==null);        //result:true
2 alert(undefined===null);      //result:false

Why is that ?. As you might already know the fact == compares only the value and === compares value and type but still not clear right, let me explain

1 alert(typeof(undefined));     //result:undefined
2 alert(typeof(null));          //result:object

As you see the type of undefined is undefined and type of null is object , null is used to represent the empty object and undefined is used to represent the property which is not yet defined in the system . which mean when you try to access the property which is not yet defined in the object , system will equate that to undefined.

getter and setter

What if when a value of property in an object is set and you want to get notified on value change. This can be accomplished using getter and setter. For example.

 1 var _property;
 2 var obj={
 3   get property(){
 4       console.log('getter called');
 5       return _property;
 6   },
 7   set property(value){
 8       console.log('setter called');
 9       _property=value;
10   }
11 };

Now, when we access the property value

1 obj.property;
2 //result:getter called

when you set the value

1 obj.property='value';
2 //result:setter called

Similarly when you want to make an object property to be read only you can define only getter. For example

1 var _property;
2 var obj={
3   get property(){
4       console.log('getter called');
5       return _property;
6   },
7 };
8 
9 obj.property='value'; //This don't affect the property value.

2.’this’ Context

What it is

As a javascript developer you might have come across this strange thing, ‘this’ keyword. There are lot of fancy definitions which are available when you google it. If i start explaining those, i’m sure the title of this book won’t possess any meaning. So let’s get dirty.

Say you having an js file and you declare a global variable in it like below.

1 var variable1=true;

Now, what the above statement will really do.

1 console.log(window.variable1); //result: true

variable1 is now part of window object when you declare it in global context.Now consider the below statement.

1 console.log(this);  //result: window {...}

At global level the value of ‘this’ is window object which is the top most object.To be more clear consider the following code.

1 function foo()
2 {
3     console.log(this);
4 }
5 
6 foo(); //or window.foo();
7 //result: window {...}

foo is part of window object, and when foo is called you are actually using window object to call the method. so the ‘this’ context inside the foo at the time of execution is window object.

Context of function inside an object

In general,

1 var obj={
2     foo:function()
3     {
4         console.log(this);
5     }
6 };
7 
8 obj.foo(); //result: obj {...}

when you call a function which is part of an object like above, the ‘this’ context will be the object holding that method. so the value of ‘this’ is depends up on how and through which object the function is invoked.

Similarly when you attaching an event handler to an event , the ‘this’ context at the time when the handler function invoked by event is window object. since during the system event call the handler will invoked in the context of window object.

Early Binding

When a function is invoked there are two things which come into picture, context and arguments, context is the value of this inside that function and arguments is the parameters passed to that function. We going to have deep look at the this context that is available inside the function and how that can be changed.

Consider the below code,

1 function foo()
2 {
3     console.log(this);
4 }
5 
6 foo();  //result:window

In the above code the value of this at the time foo invoked is window, why ?

Because foo is now part of window object, and when you invoke foo, you are actually using window object to invoke it like below.

1 window.foo(); // this is same as foo()

So the value of this at the time foo invoked is window object. The value of this for that function can be changed, this technique refer to as early binding and late binding.

What is early binding ?. When function is defined this context for that function can be fixed. so regardless of how the function is invoked this context remains same for that particular function.

In other words,We can set the this context for the function with the whatever objects we want. Consider the below code.

1 var obj={};
2 
3 function foo()
4 {
5     console.log(this);
6 }.bind(obj);    //this context is fixed as obj for this function
7 
8 foo();          //result: obj

bind function is used to fix the this context of the function to any object. In the above example the function foo’s this context is bind to the object obj. so at any point of time the value of this inside the foo will be obj.

Late Binding

Similar to early binding , late binding also used to fix the this context inside the function, but in a different way. Consider the below code

 1 var obj1={};
 2 var obj2={};
 3 
 4 function foo()
 5 {
 6   console.log(this);
 7 }
 8 
 9 foo.apply(obj1);    //result: obj1
10 foo.apply(obj2);    //result: obj2

Unless like early binding, late binding technique used to fix the this context at the time when function invoked. In the above example the apply method is used to invoke the function foo and obj1,obj2 is passed as this context to that function during the time of invoke and this is refer to as late binding.

3.Prototype

Introduction

The prototype in javascript means relation between two object’s context (means ‘this’ context). In other words prototype links two objects through context. After you linked two objects through prototype. the this context inside the function of both object is treated as same.

But the prototype linking is possible only when you create an object with constructor patter and you want to attach an object to the context of that created object. Lets have a look at how another object can be linked to prototype of constructor object.

Constructor pattern

Constructor pattern is one of the way to create objects in javascript. This pattern is used to create object which implies class like pattern. and prototype is used extensively in creating class’s like construct in javascript.You might be already aware of this, but there is much more things going on which you might not aware of. So don’t skip this part and let’s have a look.

Let’s define a class Employee with property name and functions getName and setName

 1 function Employee()
 2 {
 3     this.name='';
 4 }.prototype={
 5     getName:function(){
 6        return this.name;
 7     },
 8     setName:function(value){
 9        this.name=value;
10     }
11 }
12 
13 var empObj=new Employee();

Here the instance for the class is created using new keyword, will have detail look at this keyword in another chapter.Now lets focus on prototype.As i already told prototype is related to context. In the constructor pattern, this context is used to form the object and with prototype in place whatever object attached to it is also part of this. But there is another variant to it which is not mentioned. Employee class can be created without using the prototype. Like below

 1 function Employee()
 2 {
 3     this.name='';
 4     this.getName=function(){
 5        return this.name;
 6     };
 7     this.setName=function(value){
 8        this.name=value;
 9     };
10 }

Both way of defining the class have same effect, but the recommended way is the first approach. Property’s value should be attached to this directly and methods should be from separate object. Because for each object there is separate instance created for the properties and prototype object which has function’s will be shared between all the instance of the object. If you define the function inside the constructor , for each object there will be a separate object created for the function’s of the class as well.

Built-In Objects Vs Created Objects

The built-in types in javascript also uses the same constructor pattern to define their class like definition. and that build-in types also uses prototype to define their functions of the class. Example for such types are Date,Array,Number,String..etc.

So for objects created using built-in types or types which defined in local javascript will not have its prototype property as undefined.

1 var obj={};
2 console.log(obj.prototype);     //prototype is undefined
3 
4 var dateObj=new Date();
5 console.log(dateObj.prototype); //prototype is object

When you create object from scratch its prototype is undefined, when when you create object from built-in type its prototype is not undefined, since the prototype contains all the supporting methods for that built-in type.

4.Function Call Patterns

Introduction

What ?, a separate topic about function call, yes it might sound silly but we feel that there are some technique to discuss that you might not aware of, so lets begin.

You know what function call means and how to define a method and call it , In this section will discuss about the various options and call a function and how function call in certain pattern is treated in javascript.

Call a function

There is one common function call pattern which we use in our day to day life. and it is at the core of javascript system.

1 [variableValue](args)

For example consider a function

1 function foo()
2 {
3 }
4 
5 //or
6 
7 var foo=function()
8 {
9 }

When you declare like this there is a variable called foo which is created and a function is attached to it, so that implies the function call to be like below.

1 foo();  //Which implies pattern [variableValue](args);

Self invocation function

Function can be self invoked, consider the below example

1 (function foo()
2 {
3 })()

Before the invocation brackets , the function foo wrapped inside another bracket is treated as a value which means the above is similar to the below statement

1 (foo)()

This show’s the fact that javascript is very dynamic in nature and this made us fall in love with it.

Call and Apply

As explained in the previous sections, when a function is invoked, there are two things associated with it, context and arguments. Context refers to this inside a function, and arguments is the values passed to that function.

Call and Apply is the function in Function object which is used to invoke the function with specific context and arguments.

 1 function foo()
 2 {
 3     //consoles the context objects
 4     console.log('context:',this);
 5     for(var i in arguments)
 6     {
 7         //consoles the argument variable name
 8         console.log(i);
 9     }
10 }
11 
12 var thisObj={};
13 
14 foo.apply(thisObj,[1,2,3]);
15 foo.call(thisObj,1,2,3);
16 
17 //result
18 //context
19 //window obj
20 //1
21 //2
22 //3

In the above example function foo is implemented to console the context passed to that function and list of arguments.

The only difference between call and apply is that apply accepts the function argument as a single array, and with call it accepts each arguments as single value , you can see that in the above example.

5.Detailed Look At Closure

Introduction

In simple term, Closure is nothing but the technique that use to maintain or extend the life time of the inner scope variables. Not clear ?. let me explain in detail , but before that you need to know what scope in javascript means.

Scope

Scope in javascript defines accessibility of declared variables, there are three types of scopes in javascript.global, function, block level scopes.

Global scope

By the name, you would have guessed, when you simply declare a variable in a javascript file it becomes global variable and part of window object.and that variable is accessible everywhere in your application.

1 //this is now part of window object(i.e window.obj)
2 //and accessible everywhere.
3 var obj=true;

Function scope

The variables declared inside a function will be having the function scope and it is accessible only to that function.

1 function foo()
2 {
3     var variable1=true;
4     //variable1 is accessible only inside this function
5     console.log(variable1);
6 }
7 foo();//result true
8 console.log(variable1); //result undefined

As you see variable1 is accessible only to the function foo, once foo is invoked and function call end’s the lifetime of variable1 will be expired. and this is called function scope.

Block scope

This is also similar to function scope, the variable’s declared inside a block will be available only to that block.

1 if(i>1)
2 {
3     var variable1=true;
4     //variable1 is accessible only inside this if block.
5     console.log(variable1);
6 }
7 console.log(variable1); //result undefined

A block can be also like this

1 {
2     var variable1=true;
3     //variable1 is accessible only inside this if block.
4     console.log(variable1);
5 }
6 console.log(variable1); //result undefined

Strange right!. This is also consider as block and variables defined inside a block will have isolated scope and lifetime.

Global Scope & Local Scope

When you declare a global variable and you have block or function which has declared a same variable what will happen ?. Let’s have a look.

 1 var variable1='global';
 2 
 3 function func1()
 4 {
 5     //uses global variable
 6     console.log(variable1);
 7 }
 8 
 9 function func2()
10 {
11     var variable1='local';
12     //uses local variable
13     console.log(variable1);
14 }
15 
16 func1(); //result global
17 func2(); //result local

So you can clearly see when a variable is declared under a local scope which has same name as global scope variable, only the local scope variable is taken into account. In other words any attempt to a variable access will result only from the nearest scope.

Closure

Now, lets come to the actual topic.Closure is used to retain the lifetime of other scoped variable by maintaining external reference to the one of the inner object which have access to that local variable. Let’s look at an example.

1 function foo()
2 {
3     var name='';
4     console.log(name);
5 }
6 foo() //after this point the lifetime of name is expired

After the foo is invoked the lifetime of variable ‘name’ which is declared inside foo will be expired.

Now let’s consider what if we need to maintain lifetime of variable ‘name’ even after foo function call. Let’s have a look.

 1 function foo()
 2 {
 3     var name='';
 4 
 5     return {
 6         getName:function(){
 7             return name;
 8         },
 9         setName:function(value){
10             name=value;
11         }
12     }
13 }
14 
15 var obj=foo();
16 obj.setName('tony');
17 obj.getName();
18 //still have access to name variable
19 //due to external reference.

As you see in the above example, the variable name is declared inside foo and an object containing getName and setName is returned at end of the function.so when you invoke foo, an object will be returned and because of that object’s external reference the lifetime of variable ‘name’ will be maintained. Since the returned object’s scope is in the inner scope of foo.

One thing to note here is , using this technique we can achieve the private variable encapsulation. In the above example, after foo call, you cannot access the variable ‘name’ directly , instead the function inside the object is used to get/set the variable values.

This is called closure !

7. Inheritance

Introduction

In traditional way, Inheritance in javascript can be achieved using prototype chaining. The detailed look on prototype chain is explained in the previous chapter, but there is more flexibility needed when it comes to actual inheritance, and this is provided in ECMAScript 5. It is called Object.create().Lets have a detailed look on what it can do.

Object.create()

This method of creating object is very useful when want to create object which need to inherit another object. Let’s look at the below example.

Let’s consider the object

1 var objParent={
2     property1:1,
3     property2:2
4 };

Now, an another object should be created which should inherit objParent, which means all the properties of the parent object should be accessible through child object.

 1 var objChild=Object.create(objParent,{
 2   property:3,
 3   property:4
 4 });
 5 
 6 //all the property of objParent is now accessible
 7 //through objChild
 8 console.log(objChild.property1);
 9 console.log(objChild.property2);
10 console.log(objChild.property3);
11 console.log(objChild.property4);

Here, Object.create accepts the first argument as prototype object. But after object is created, still the prototype of both the objects is undefined. But the prototype relation can be checked using isPrototypeOf function.Like below

1 objParent.isPrototypeOf(objChild); //return true

Inheritance with constructor

Constructor patter can be used to create the object’s with new keyword. Like below

 1 function Shape()
 2 {
 3     this.width=0;
 4     this.height=0;
 5 }.prototype={
 6     print:function(){
 7         console.log('width:'+this.width+' height:'+this.height);
 8     }
 9 }
10 
11 var shapeObj=new Shape();
12 console.log(shapeObj.width);

The above code represents Shape class with properties width and height and method print, now i’m going to create a class Rectangle which inherits Shape. Let’s see how to do that using Object.create.

 1 function Rectangle()
 2 {
 3     //Property Inheritance
 4     //calling super class constructor
 5     //this will attach all the properties belong to Shape class
 6     Shape(this);
 7 }.prototype={
 8     area:function()
 9     {
10         return this.width*this.height;
11     }
12 }
13 
14 //Method Inheritance
15 //this line will clone the Shape's prototype
16 //and attach all the method's to Rectangle's prototype
17 Rectangle.prototype=Object.create(Shape.prototype);
18 
19 var rect-new Rectangle();

Here, property is inherited by calling super class constructor in Rectangle function. and methods of Shape is inherited by creating new object with Object.create with prototype as Shape’s prototype and and attaching it to Rectangle’s prototype.

But one problem is here, when you see the value of Rectangle.prototype.constructor , it points to Shape which is not correct, so one more line need to be added.

1 Rectangle.prototype.constructor=Rectangle;

Now, the above statement make sure that all the objects created with Rectangle(), their constructor is pointing to Rectangle object and not Shape object.

That concludes the inheritance in javascript !

7.Conclusion

Javascript is like an ocean, even though there are patterns and practices which are concluded by the community , still there are lot of patterns and practices yet to be discovered by this world. Well i hope this book have given you a head start on your journey towards the advanced javascript world. Javascript is more about the exploration than learning. And it is not about understanding the language, it is about how you are aligning with it and make use of its powerful construct that will lead you to the path of success.

Thanks and good luck !