Javascript prototypes
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;}
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 atStudent.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
toStudent.prototype
and we can able to access it with instancestudObj
also.
Student.prototype.info = {country: 'India'};
console.log(studObj.info);
// {country: 'India'}