vikramlc / Javascript

0 stars 0 forks source link

Constructors functions and Prototypes #12

Open vikramlc opened 4 years ago

vikramlc commented 4 years ago

image

Example:

// class Person {
//     name = 'Max';

//     constructor() {
//         this.age = 30;
//     }

//     greet() {
//         console.log(`Hi, I am ${this.name} and I am ${this.age} years old.`);
//     }
// }

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.`);
    };
}

const person = new Person();
person.greet();
vikramlc commented 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();
vikramlc commented 4 years ago

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

image image image

vikramlc commented 4 years ago

Prototype Chaining: image

vikramlc commented 4 years ago

prototype property on a Person object:

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();

vikramlc commented 4 years ago

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
vikramlc commented 4 years ago

Methods in Classes and in Constructors: For Classes:

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)
vikramlc commented 4 years ago

Setting and Getting Prototypes:

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();

vikramlc commented 4 years ago

Creating Objects with Object.create() and Object.defineProperty():

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

vikramlc commented 4 years ago

image