Open vikramlc opened 4 years ago
How the javascript works behind functions:
function Person() {
this = {};
this.name = 'Max';
this.age = 30;
this.greet = function() {
console.log(`Hi, I am ${this.name} and I am ${this.age} years old.`);
};
return this;
}
const person = new Person();
person.greet();
What are Prototypes? Prototypes can be a confusing and tricky topic - that's why it's important to really understand them.
A prototype is an object (let's call it "P") that is linked to another object (let's call it "O") - it (the prototype object) kind of acts as a "fallback object" to which the other object ("O") can reach out if you try to work with a property or method that's not defined on the object ("O") itself.
EVERY object in JavaScript by default has such a fallback object (i.e. a prototype object) - more on that in the next lectures.
It can be especially confusing when we look at how you configure the prototype objects for "to be created" objects based on constructor functions (that is done via the .prototype property of the constructor function object).
Consider this example:
function User() {
... // some logic, doesn't matter => configures which properties etc. user objects will have
}
User.prototype = { age: 30 }; // sets prototype object for "to be created" user objects, NOT for User function object
The User function here also has a prototype object of course (i.e. a connected fallback object) - but that is NOT the object the prototype property points at. Instead, you access the connected fallback/ prototype object via the special proto property which EVERY object (remember, functions are objects) has.
The prototype property does something different: It sets the prototype object new objects which you create with this User constructor function will have.
That means:
const userA = new User();
userA.__proto__ === User.prototype; // true
userA.__proto__ === User.__proto__ // false
Prototype Chaining:
prototype property on a Person object:
The below example displays the same.
function Person() {
this.name = 'Max';
this.age = 30;
this.greet = function() {
console.log(`Hi, I am ${this.name} and I am ${this.age} years old.`);
};
}
Person.prototype = { printAge() { console.log(this.age); } };
console.dir(Person);
const person = new Person(); person.greet();
// 1. Javascript behind the scene checks if the printAge function is present on the Person object. // 2. If it is NOT present then it checks under the prototype property of the object. // 3. Then it checks under the proto property of the object. person.printAge();
Working with prototypes: This is how the prototype should be edited:
Person.prototype.printAge = function() {
console.log(this.age);
}
The prototype chaining ends with Object.prototype:
Object.prototype
Methods in Classes and in Constructors: For Classes:
class AgedPerson {
printAge() {
console.log(this.age);
}
}
class Person extends AgedPerson { name = 'Max';
constructor() {
super();
this.age = 30;
}
greet() {
console.log(`Hi, I am ${this.name} and I am ${this.age} years old.`);
}
}
const p = new Person(); const p2 = new Person();
// Person {name: "Max", age: 30} // age: 30 // name: "Max" // proto: AgedPerson // constructor: class Person // greet: ƒ greet() // proto: // constructor: class AgedPerson // printAge: ƒ printAge() // proto: Object console.log(p);
// Person {name: "Max", age: 30} // age: 30 // name: "Max" // proto: AgedPerson // constructor: class Person // greet: ƒ greet() // proto: // constructor: class AgedPerson // printAge: ƒ printAge() // proto: Object console.log(p2);
console.log(p.proto === p2.proto); // true
**_Equivalent For Functions:_**
- The greet function is now shared across any number of objects created.
function Person() { this.name = 'Max'; this.age = 30; }
Person.prototype.greet = function() {
console.log(Hi, I am ${this.name} and I am ${this.age} years old.
);
};
const p = new Person(); console.log(p);
![image](https://user-images.githubusercontent.com/44239429/85035345-ad623680-b1a0-11ea-888d-f736543cd1e6.png)
Setting and Getting Prototypes:
const course = {
title: 'Javascript',
rating: 5
};
console.log(Object.getPrototypeOf(course));
- **Setting the Prototype for the object:**
const course = { title: 'Javascript', rating: 5 };
Object.setPrototypeOf(course, {
printRating: function() {
console.log(Rating: ${this.rating}/5
);
}
});
course.printRating();
Creating Objects with Object.create() and Object.defineProperty():
const student = Object.create({
printProgress: function() {
console.log(this.progress); // 0.8
}
}, {
name: {
configurable: true,
enumerable: true,
value: 'Max',
writable: true
}
});
Object.defineProperty(student, 'progress', { configurable: true, enumerable: true, value: 0.8, writable: true });
student.printProgress();
// Above is equivalent to below: // const student = { // name: 'Max', // progress: 0.8 // }
Example: