Prototypes & Objects

Use prototypes for :
- Methods
- Static properties

I use constructor for :
- Methods which can change (closure, bind etc.)
- Variable properties

It makes the code more readable, and you get more of its logic : why would you duplicate a class variable, a class constant or a method shared by all the instances ?

If it's in the prototype, it's shared by all the objects.
If it's in the constructor, it's not.

So, mostly, readability and refactorability.

All objects are linked via prototype, this is the chain

Vehicle{}
Vehicle.prototype = Vehicle; // level 1
Car = new Vehicle();
Car.prototype = Vehicle.prototype; // level 2
Engine = new Car();
Engine.prototype = Car.prototype; // level 3

Creating

When creating a new object a prototype is applied.

var a = {};
var a = function() {}; // functions also gets a proto

Inheritance of object without prototype (lightweight)

var Vehicle = {
   wheels: 4,
   automatic: true
};
 
var Car = Object.create(Vehicle, { // creates a prototype link to Vehicle
    color: {
       enumerable: false,
       writable: false,
       configurable: false,
       value: "red"
    }, 
    model: { 
       value: 'Hatchback'
    }
});
 
console.log(Car.wheels);// 4
console.log(Car.color); // red 
 
Car.color = 'pink'; 
console.log(Car.color); // red
 
Car.wheels = 3; 
console.log(Car.wheels); // 3

Prototypical Inheritance (get and set)

myObject.name = 'John' // This is a set() method
var name = myObject.name // This is get() method

Transversing means it will look up the tree to get() or set() a value.

var object = {
  a: 2
}
 
var newObject = Object.create(object); // Inherit
/* {} __proto__
       a: 2
*/
 
console.log(newObject); 
/*
Object {
  a: 2
}
*/
 
newObject.name = "John";
 
/* name: "John"
   __proto__: 
       a: 2
*/
 
console.log(newObject);  
 
/* Result */
 
/* Object {
  a: 2,
  name: "John"
} */
 
newObject.name = 'Peter';
 
console.log(newObject);  
 
/* Object {
  a: 2,
  name: "Peter"
} */

Setting values only effects that object down (top to bottom)

var object = {
  a: 2
}
 
var newObject = Object.create(object); // Inherit
 
object.a = 3;
 
console.log(object); // 3
 
newObject.a = 5;
 
console.log(object); // 3
console.log(newObject); // 5

The "new" keyword creates the prototype

function User() {
 
} 
 
var a = new User();
 
var is = Object.getPrototypeOf( a ) === User.prototype; // true
 
console.log(is); // true

Prototype Style Example

/* User */
function User(name, age) {
  this.name = name;
  this.age = age;
}
 
User.prototype.myName = {
  get name() {
   return this._name; 
  }
}
 
User.prototype.age = {
  get age() {
   return this._age; 
  }
}
 
/* Student */
function Student(name, age) {
  User.call(this, name, age); // If we need to set anything in User for our Student when initialising
}
 
Student.prototype = Object.create(User.prototype); // important, now linked to User.
 
/* Create a new student with prototype methods  */
var newStudent = new Student('John', 22); 
 
console.log(Student.prototype.isPrototypeOf( newStudent )); // true  
 
console.log('My name is ' + newStudent.name + ' and I am ' + newStudent.age + ' years old');
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License