loading...
Cover image for Objects and Prototypes in JavaScript 😳 πŸ€”

Objects and Prototypes in JavaScript 😳 πŸ€”

irenejpopova profile image Irena Popova πŸ‘©πŸ»β€πŸ’» ・5 min read

JavaScript is a prototype-based language, therefore understanding the prototype object is one of the most important concepts. I will give you a short overview of the Prototype object through various examples. Before reading this article, make sure that you have a basic understanding of the this reference in JavaScript.

πŸ›‘ Remember:
πŸ‘‰ Whenever you create a function using JavaScript, JavaScript engine adds a prototype property inside a function, Prototype property is basically an object (also known as Prototype object) where we can attach methods and properties in a prototype object, which enables all the other objects to inherit these methods and properties.

πŸ‘‰ There are different ways to create an object, one of the way is to create an object using function constructor.
πŸ”»


// function constructor 
function Person(name, job, yearOfBirth){    
    this.name= name; 
    this.job= job; 
    this.yearOfBirth= yearOfBirth; 
} 
// this will show Person's prototype property. 
console.log(Person.prototype);

πŸ‘‰ we can add a method calculateAge() to the Prototype property in a Person function constructor which will inherit by the different objects. See the code bellow:

function Person(name, job, yearOfBirth){    
    this.name= name; 
    this.job= job; 
    this.yearOfBirth= yearOfBirth; 
} 
Person.prototype.calculateAge= function(){ 
    console.log('The current age is: '+(2019- this.yearOfBirth)); 
} 
console.log(Person.prototype); 

πŸ‘‰ Type the code in the browser console and see the output and that calculateAge() method gets added to the Prototype property.

  • Let's create 2 different objects which will inherit calculateAge() method.

πŸ›‘ Remember:

πŸ‘‰ When a certain method(or property) is called, it first checks inside the object but when it doesn’t find, then search moves on Object’s prototype.
πŸ”»


function Person(name, job, yearOfBirth){   
    this.name= name; 
    this.job= job; 
    this.yearOfBirth= yearOfBirth; 
} 
// adding calculateAge() method to the Prototype property 

Person.prototype.calculateAge= function(){  
    console.log('The current age is: '+(2019- this.yearOfBirth)); 
} 
console.log(Person.prototype); 

// creating Object Person1 
let Person1= new Person('Irene', 'teacher', 1985);  
console.log(Person1) 
let Person2= new Person('Tim', 'Developer', 1982); 
console.log(Person2) 

Person1.calculateAge(); 
Person2.calculateAge(); 

⚑
πŸ›ŽοΈ πŸ‘‰ The two Objects Person1 and Person2 were created using constructor function Person, when we called Person1.calculateAge() and Person2.calculateAge(), as first it will check whether it is present inside Person1 and Person2 object, if it is not present, it will move Person’s Prototype object and prints the current age, which shows Prototype property enables other objects to inherit all the properties and methods of function constructor.

πŸ‘‰ Considering the fact that almost everything in JavaScript is an object, object oriented JavaScript code is very different from other object-capable languages.

πŸ›‘ JavaScript objects are very different in the way they are created. There is no requirement for a class.
β—πŸ‘‰ Object instances can be created using the new operator:
πŸ”»

let Animal = new Object() {
 // ...
}

or with a function constructor:

function Animal() {
 // ...
}

πŸ‘‰ JavaScript objects are very flexible. While classic object oriented languages allow only property modification or property slots, JavaScript allows objects to modify their properties and methods;
πŸ›‘ πŸ‘‰ JavaScript objects have both property and method slots. πŸ€”

πŸ‘‰ All JavaScript objects are created from the Object constructor: 😳
πŸ”»

var Animal = function(name, canItSwim) {
  this.name = name;
  this.canItSwim = canItSwim;
}

πŸ›‘ πŸ‘‰ The prototype allows us to add new methods to objects constructors, this means that the following method now exists in all instances of Animal.
πŸ”»

Animal.prototype.doesItFly = function() {
  if (this.canItSwim) {
    console.log(`${this.name} can swim`);
  } else {
    console.log(`${this.name} has fly`);
  }
};

Object instances of Animal can be now created:
πŸ”»

// for this example consider dolphins can swim and horse cannot
let dolphin = new Animal("dolphin", true);
dolphin.doesItSwim(); // dolphin can swim

let horse = new Animal("horse", false);
horse.doesItSwim(); // horse has 

πŸ‘‰ The prototype of the Animal object is now the basis for inheritance, the doesItSwim method is accessible to both dolphin and horse because the prototype of Animal has this method. The prototype property is shared amongst all its instances and is accessible via the__proto__ property of a particular instance.

πŸ‘‰ Now, because of the existence of method slots and a common prototype instance property being shared across all instances, some very neat tricks are possible:
πŸ”»


horse.__proto__.doesItSwim = function() {
  console.log(`the horse never swims`);
};

horse.doesItSwim(); // the horse never swims
dolphin.doesItSwim(); // the horse never swims

πŸ›‘ Change one instance’s prototype property or method, all instances of the object are affected. This means we could be deleting stuff as well. A horse tired of swimming could potentially do this:🀣 🀣 🀣
πŸ”»

delete horse.__proto__.doesItSwim
dolphin.doesItSwim();

//TypeError: dolphin.doesItSwim
// is not a function

Now no one gets to swim. 🀣 🀣 🀣

This is just a funny example to show how fundamental the prototype is to the Object system in JavaScript and how it can be quite tricky to people from other object oriented languages.

πŸ‘‰ With the ES6 syntax, JavaScript has been provided the feature to create classes.

πŸ›‘ However, the concept of true classes does not exist in JavaScript but it is emulated through prototype and the class syntax is just syntactic sugar around it. Therefore, understanding this behavior is important to realize the convenience and limitations of ES6 classes.

With the new class syntax, Animal would be defined as:
πŸ”»


class Animal {
  constructor (name, canItWalk) {
    this.name = name;
    this.canItWalk = canItWalk;
  }

  doesItSwim () {
   if(this.canItSwim)
    console.log(`${this.name} can swim`);
   else
    console.log(`${this.name} has walked`);
  }
}

let horse = new Animal("horse", true);
horse.doesItWalk(); //horse can walk

πŸ‘‰ This does not mean it brings nothing new to the offer for prototype users, some pitfalls can be avoided by using ES6 classes, like making the new keyword mandatory for creating instances.
πŸ”»


let dolphin = Animal("dolphin", false);

//Output: TypeError: Class constructor Animal cannot be invoked without 'new'

πŸ‘‰ This is actually a good thing, since it prevents accessing the wrong context when using the object properties and methods, which is usually the global scope or the window object.

πŸ›‘ When a function is created in JavaScript, the JavaScript engine adds a prototype property to the function.
πŸ›‘ This prototype property is an object (called a prototype object) that has a constructor property by default.
πŸ›‘ The constructor property points back to the function on which prototype object is a property.
Look at the following example:
πŸ”»


function Human(firstName, lastName) {
    this.firstName = firstName,
    this.lastName = lastName,
    this.fullName = function() {
        return this.firstName + " " + this.lastName;
    }
}

var person1 = new Human("John", "Doe");

console.log(person1)

So objects in JavaScript have an internal property known as prototype.
It is simply a reference to another object and contains common attributes/properties across all instances of the object.
πŸ›‘ An object’s prototype attribute specifies the object from which it inherits properties.

πŸ”»


let numArray = [1,2,-8,3,-4,7];

πŸ‘‰ The Array object has a prototype Array.prototypeand the object instance, num, inherits the properties of the Array object.

Happy Coding & Have fun!🀩 πŸ€–

Alt Text

Posted on by:

Discussion

markdown guide