Javascript prototypes

Object prototypes in Javascript

prototype: an original model on which something is patterned

Object prototypes in Javascript

  • Every object in JavaScript has a built-in property, which is called its prototype.
  • The prototype is itself an object, so the prototype will have its own prototype, making what's called a prototype chain.
  • The chain ends when we reach a prototype that has null for its own prototype.
  • In javascript, new objects can be created with a constructor function, like new F().
  • If F.prototype is an object, then the new operator uses it to set [[Prototype]] for the new object.

note: JavaScript had prototypal inheritance from the beginning. It was one of the core features of the language.

Default properties of prototype object

  • Every javascript function or an object which is created with new keyword has below properties.
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
__proto__: (...)
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
  • Let's see an example

function Person(name, age){
    this.name = name
    this.age = age
}

const obj = new Person('John', 25);
console.log(obj.hasOwnProperty)
// ƒ hasOwnProperty() { [native code] }
console.log(obj.isPrototypeOf)
// ƒ isPrototypeOf() { [native code] }
console.log(obj.constructor)
// ƒ Person(name, age){ this.name = name; this.age = age;}
- Let's talk about constructor a bit. A constructor enables us to provide any custom initialization that must be done before any other methods can be called on an instantiated object. - Every object in javascript has a constructor by default. - default constructor function(){} - The default constructor functionality can be overriden

Why use prototypes?

  • It's very simple They use less memory
  • We can add dynamic properties to function/class/object

how to save memory with prototype?

function Animal(name){
    // this is the function/class and the constructor at the same time.
    this.walk = function(){};
    this.talk = function(){};
    this.jump = function(){};
}
  • If we call new Animal() then it the constructor is called immediately. This is where the problem of performance occurs.
  • We defined three functions inside the constructor, this means every single time the object is instantiated then those functions are defined a new.
  • We are creating duplicate functions every single time.
  • If we create two or three objects, then the problem is negligible.
  • But if we create a herd of animals, we start seeing our memory growing because for each animal we are creating a whole new method at run time time.
  • The solution to the problem is to use Prototypes.
  • prototype allow us to define the methods once, as a blue print, and have each instance build from it.
function Animal(){};
Animal.prototype.walk = function(){};
Animal.prototype.talk = function(){};
Animal.prototype.jump = function(){};

how to add dynamic properties with javascript prototypes?

  • Let's consider below code
function Student() {
    this.name = 'John';
    this.gender = 'M';
}

var studObj = new Student();

console.log(Student.prototype); // object
console.log(studObj.prototype); // undefined
console.log(studObj.__proto__); // object

console.log(typeof Student.prototype); // object
console.log(typeof studObj.__proto__); // object

console.log(Student.prototype === studObj.__proto__ ); // true
  • From the above code, we can understand that prototype object is available at Student.prototype when it's not instantiated. but, after creating the object it's referenced in property __proto__
  • It allows the instance objects to access the prototypes properties when it's updated dynamically.
  • Let's add an attribute info to Student.prototype and we can able to access it with instance studObj also.
Student.prototype.info = {country: 'India'};
console.log(studObj.info);
// {country: 'India'}

References: