JavaScript - Closures, Prototypes & Inheritance

Objects


  • a hash of key:value pairs;
  • the key can be a Number or a String;
  • the value can be anything and it can be called a property;
  • if a value is a function, it can be called a method.


Objects


var animal = {
  isDog: true,
  name: 'Sparky',
  bark: function(){
    return 'Bark!'
  }
} 

Arrays


  • also objects;
  • have numeric properties that are auto-incremented;
  • have a length property;
  • inherits some methods like:
    • push();
    • splice();
    • sort();
    • join();
    • and more.

ARRAYS


var array = [1,2,3];

>> array.length //3

array.push(4);

>> array.length //4


JSON


  • JavaScript Object Notation;
  • uses objects and arrays;
  • objects can't have methods;
  • all objects keys must be wrapped in quotes.

Functions


  • also objects;
  • have properties and methods;
  • can be copied, deleted, augmented;
  • special, because can be invoked;
  • all functions return a value (implicitly undefined);
  • can return other functions.

FUNCTIONS


//Function Declaration
function fn(x){
   return x;
}

//Function Expression
var fn = function(){
   return x;
}

Constructor Functions


  • return this when they are invoked with new;
  • this can be modified before it's returned;
  • can return another object.


Constructor Functions Naming Convention


  • MyConstrunctor
  • myFunction

Constructor Functions


var Person = function(name){
   this.name = name;
   this.sayName = function(){
      return 'My name is ' + this.name;
   };
};

//Create new instance
var john = new Person('John');

>> john.sayName(); //John
>> john instanceof Person //true
>> john instanceof Object //true

Prototype


  • a property of the function object;
  • can be overwritten or augmented.

PROTOTYPE


var Person = function(name){
   this.name = name;
   this.sayName = function(){
      return 'My name is ' + this.name;
   };
};

//Create new instance
var james= new Person('James');

//Augment the prototype object
Person.prototype.changeName = function (newName) {
   this.name = newName;
};

james.changeName('Joe');

>>james.sayName(); //Joe
  • changeName() is a property of the prototype object;
  • it behaves as if it's a property of james object.
  • __proto__


    • it's not directly exposed in all browsers;
    • it's a reference to constructor prototype property.

    Prototype chain



    PROTOTYPE Example


    var Person = function(name){
       this.name = name;
    };
    
    Person.prototype.changeName = function (newName) {
       this.name = newName;
    };
    
    Person.prototype.sayName = function(){
       return 'My name is ' + this.name;
    };
    
    var james= new Person('James');
    
    >> james.hasOwnProperty('changeName'); //false
    >> james.__proto__.hasOwnProperty('changeName'); //true
    


    INHERITANCE


    var Dad = function(kids){
       this.kids = kids || 0;
    };
    
    Dad.prototype = new Person();
    Dad.prototype.constructor = Dad;
    
    var dad = new Dad(2); //{kids:2, name:undefined, changeName:function, sayName:function}
    
    >>dad instanceof Dad; //true
    >>dad instanceof Person; //true>>dad instanceof Object; //true

    Variables scope


    • no block scope

    if(true){
       var inside = 1;
    }
    
    >>inside //1

    Function Scope


    • every variable is global unless it’s in a function and is declared with var;
    • global namespace should be kept clean;
    • function scope is very helpful;

    function fn(){
       var private = true;
       //private it's available here
    }
    
    >>private //undefined

    Immediately-invoked functions


    (function(){
       var a = 1;
       var b = 2;
    
       alert(a + b);
    })();
    

    Closures


    • Closures are functions that refer to independent (free) variables.;
    • In other words, the function defined in the closure 'remembers' the environment in which it was created. 


    (function(win){
      var a = 1, b = 2,
          //Closure
          sum = function(){
             return a + b; 
          }
    
      win.sum = sum;
    })(window);
    
    >> sum()//3
    

    Closures


    //bad
    for (var i = 0; i < 5; i++) { 
       window.setTimeout(function(){ 
          alert(i); // will alert 5 every time
       }, 200); 
    } 
    
    //good
    for (var i = 0; i < 5; i++) { 
       (function(index) {
          window.setTimeout(function() { alert(index); }, 100);
       })(i);
    }
    

    JavaScript Closures, Prototypes & Inheritance

    By Alexe Bogdan

    JavaScript Closures, Prototypes & Inheritance

    • 1,094