Objects and Prototypes in JavaScript 😳 🤔
Tags: javascript, beginners, codenewbie, webdev
Published: 2020-08-01 14:05:19

JavaScript is a <b>prototype-based language,</b> 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.

🛑 <b> Remember:</b>
  👉 Whenever you create a function using JavaScript, JavaScript engine adds a prototype property inside a function, Prototype property is basically an <b>object (also known as Prototype object)</b> where we<b> can attach methods and properties in a prototype object,</b> which enables all the other objects to<b> inherit these methods and properties.</b>

👉 There are different ways to create an object, one of the way is to create an object using function constructor.
🔻
```js

// 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:

```js
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<b> method(or property) is called,</b> it first checks inside the object but when it doesn’t find, then <b>search moves on Object’s prototype.</b>
🔻
```js

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:
🔻
```js
let Animal = new Object() {
 // ...
}
```
or with a function constructor:
```js
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 <b>property and method slots.</b> 🤔

👉 All JavaScript objects are created from the<b> Object constructor:</b> 😳 
🔻
```js
var Animal = function(name, canItSwim) {
  this.name = name;
  this.canItSwim = canItSwim;
}
```
🛑 👉 The prototype allows us to add <b>new methods</b>  to <b>objects constructors,</b> this means that the following method now exists in all instances of `Animal`.
🔻
```js
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:
🔻
```js
// 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 <b>prototype instance property</b> being shared across all instances, some very neat tricks are possible:
🔻
```js

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:🤣 🤣 🤣
🔻
```js
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 <b>Object system in JavaScript</b> 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 <b>classes.</b>

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

With the new class syntax, Animal would be defined as:
🔻
```js

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,<b> like making the new keyword mandatory for creating instances.</b>
🔻
```js

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 <b>global scope </b> or the <b> window object.</b>

🛑 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 <b>constructor </b> property by default. 
🛑 The constructor property points back to the function on which prototype object is a property.
Look at the following example:
🔻
```js

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 <b>internal property</b> known as <b>prototype</b>.
It is simply a reference to another object and contains common <b>attributes/properties</b> across all instances of the object.<b> 
🛑 An object’s prototype attribute specifies the object from which it inherits properties.</b>
🔻
```js

let numArray = [1,2,-8,3,-4,7];
```
👉 The Array object has a prototype `Array.prototype `and the object instance, `num`, <b>inherits the properties of the Array object.</b>


<b> Happy Coding & Have fun!🤩 🤖 </b> 

![Alt Text](https://media.giphy.com/media/Zx0Ploq51axjKTZzgZ/giphy.gif)