Programming languages have evolved significantly since the first electronic computers were developed in the 1940s. Initially, programmers used machine language or assembly language to write code, which was tedious and time-consuming. The first high-level programming language, FORTRAN, was developed in the mid-1950s, followed by COBOL and BASIC in the 1960s.

In the 1970s, programming languages continued to evolve, with the development of languages like Pascal, C, and Ada. These languages were designed to be more efficient and easier to read and write than earlier languages. They also introduced new programming concepts such as data structures and procedural programming.

In the 1980s, object-oriented programming (OOP) was invented, which revolutionized the way programmers wrote code. OOP is a programming paradigm that organizes data and behavior into reusable objects, making code more modular and easier to maintain. The first object-oriented language was Simula, developed in Norway in the 1960s. However, it was not until the 1980s, when languages like Smalltalk, C++, and Objective-C were developed, that OOP became popular.

Today, there are many different programming languages, each with its own strengths and weaknesses. Some of the most popular languages include Java, Python, JavaScript, and C#. The evolution of programming languages has made it easier for programmers to write code and develop software, and has helped to make technology more accessible to people around the world.

Prototype inheritance

JavaScript have only Objects (pointers) and Primitive (string, number, bool) types of variables.

Primitive values are connected to corresponding Objects and behave like they are instances. For example: 'abc'.substr(2) would actually call String.substr method applied to 'abc' as this.

Animal

Lets create a classical example of inheritance: AnimalMammalCat

Every function can be called with a new keyword, and it would create an instance of an object. Such function is called a constructor.

this in the constructor points to a created object:

var Animal = function(){ 
  this.bornDate = new Date(); 
};
Animal.prototype = {
  alive: true,
  isAlive: function(){
      return this.alive;
  }
};

var animalInstance = new Animal();
console.log('The animal '+ (animalInstance.isAlive() ? 'is': 'is not')+' alive');
// Would output "The animal is alive"
console.log('The animal was born at '+ animalInstance.bornDate);
// Would output "The animal was born at CURRENT_DATE"

So, what does the animalInstance really looks like? animalInstance is just an object with a bornDate property.

{bornDate: new Date()} but it has an Animal as a prototype. So when we want to get animalInstance.alive — the property alive would be searched in the instance, and it would not be found. After that the prototype of the object would be used (Animal.prototype) and the property alive would be searched there. And there it exists, so it would be returned. Animal.prototype can also have a prototype and the property would be searched till the null prototype, and if it is the case — undefined would be returned.

instanceof

instanceof method can be used to check if object is an instance of some constructor

console.log( animalInstance instanceof Animal ) // true

hasOwnProperty

hasOwnProperty returns true if Object have got some property. It is very useful to divide own properties and some properties from a prototype chain.

By the way, search of hasOwnProperty method in animalInstance would be done in such way:

  1. Search in animalInstance object ({bornDate: new Date()}). No there is no hasOwnProperty method here
  2. Getting the prototype of Animal
  3. Searching in the Animal.prototype ({alive: true, isAlive: function}). There is also no such method
  4. Going to the Animal.prototype.prototype (Object.prototype). There are a lot of methods there, like toString, valueOf, and hasOwnProperty is also there. So hasOwnProperty would be taken and called on our animalInstance
console.log( animalInstance.hasOwnProperty('alive') ) // false, because 'alive' lives in a prototype

// true, because we put this property in 'this' in the Animal constructor
console.log( animalInstance.hasOwnProperty('bornDate') )

Mammal

Mammal would be derived from an Animal and would only differ with hasMilk property

var Mammal = function(){
    Animal.apply(this, arguments);
    /* 
    It is important to call the parents constructor on our current object,
    so it also can do the whole initialization sequence.
     */
}
Mammal.prototype = new Animal();
Mammal.prototype.hasMilk = true;

var ourMammal = new Mammal();

console.log(ourMammal instanceof Mammal) // true
console.log(ourMammal instanceof Animal) // true, because ourMammal__proto__.prototype === Animal.prototype

console.log(animalInstance instanceof Mammal) // false, because not all Animals are Mammals

Cat

Cat would be derived from a Mammal and would be able to meow

var Cat = function(){
  Mammal.apply(this, arguments);	
};
Cat.prototype = new Mammal();
Cat.prototype.meow = function(){
    console.log('meow')
};

var barsik = new Cat();

console.log(barsik.meow()) // would print 'meow'
console.log(barsik instanceof Mammal) // true
console.log(barsik instanceof Animal) // true
console.log(barsik instanceof Cat) // true

New keyword

There are a lot of frameworks that simplify creating objects by omitting the new keyword. It helps a lot to all people that do not know all nuances of js. Let me show how to achieve this behavior.

var Dog = function(){
  console.log(this)
  // let check: if this is not a dog → return new Dog. Otherwise just continue
  
  if(!(this instanceof Dog))
    return new Dog();	
    
  Mammal.apply(this, arguments);
};
Dog.prototype = new Mammal();
Dog.prototype.bark = function(){
    console.log('bark, bark')
};

var tuzik = Dog();
/*
 1. It would log 'window' Object, because Dog function is stored in the window context, and 
    can be called as 'window.Dog()'. This happens because we omitted the 'new' keyword
 2. It would log an empty Object (it is our not initialized dog!)
 */

console.log(tuzik.meow()) // would print 'meow'
console.log(tuzik instanceof Mammal) // true
console.log(tuzik instanceof Animal) // true
console.log(tuzik instanceof Cat) // false
console.log(tuzik instanceof Dog) // true

Classes, extending

Different frameworks like jQuery, Ext.js, Backbone, etc. have their own class systems. All of them are well documented and hides prototype based implementation under the hood.