MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Moștenirea prototipurilor

JavaScript suportă moștenirea, permițându-ne să creăm noi tipuri de obiecte și să moștenim funcționalitatea lor de la obiecte deja existente. Cu toate acestea, trebuie să înțelegem că moștenirea în JavaScript diferă de cea din alte limbaje populare precum Java, C++, C# și altele.

În JavaScript, moștenirea este bazată pe obiecte (nu pe clase sau tipuri), fiind cunoscută și sub denumirea de moștenire a prototipurilor sau moștenire prototipală.

Pentru a crea un obiect bazat pe un anumit prototip, se folosește funcția Object.create(), la care se transmite prototipul ce urmează să fie moștenit:

const person = {
   name: "",
   age: 0,  
   print: function(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
};

const employee = Object.create(person);  // employeefolosește prototipul obiectului person

//primim prototipul
console.log(employee.__proto__);     // {name: "", age: 0, print: ƒ}

employee.name = "Tom";
employee.age = 39;
employee.print();    // Name: Tom  Age: 39

În acest caz, obiectul "employee" este creat pe baza prototipului obiectului "person", esențialmente, obiectul "employee" moștenește prototipul obiectului "person". Datorită acestei moșteniri, obiectul "employee" dispune de aceleași proprietăți și metode definite în obiectul "person".

În plus, obiectele pot defini propriile lor proprietăți și metode. De exemplu:

const person = {
   name: "",
   age: 0,
   print: function(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
};

const employee = Object.create(person);  // Employee folosește prototipul obiectului "person"

employee.name = "Tom";
employee.age = 39;
employee.company = "Google";  // proprietate nouă
// metodă nouă
employee.work = function(){
   console.log(`${this.name} lucrează la ${this.company}`);
}
employee.print();    // Name: Tom  Age: 39
employee.work();    // Tom lucrează la Google

În acest caz, obiectul "employee" definește în plus proprietatea "company" și metoda "work".

La nevoie, se pot redefini metodele moștenite:

const person = {
   name: "",
   age: 0,  
   print: function(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
};
const employee = Object.create(person);

employee.name = "Tom";
employee.age = 39;
employee.company = "Google";
// redefinim metoda print
employee.print = function(){
   console.log(`Name: ${this.name}  Age: ${this.age} Company: ${this.company}`);
}
employee.print();    // Name: Tom  Age: 39  Company: Google

Aici redefinim funcția "print" pentru a afișa și compania angajatului. Se poate merge și mai departe și extinde lanțul de moștenire:

const person = {
   name: "",
   age: 0,  
   print: function(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
};
// Obiectul "employee" moștenește prototipul obiectului "person"
const employee = Object.create(person);
employee.company = "";

// Obiectul "manager" moștenește prototipul obiectului "employee"
const manager = Object.create(employee);
// Redefinim metoda "print"
manager.print = function(){
   console.log(`Name: ${this.name}  Age: ${this.age}\nManager in ${this.company}`);
}
manager.name = "Bob";
manager.age = 43;
manager.company = "Microsoft";
manager.print();    // Name: Bob  Age: 43  
                   // Manager in Microsoft

Astfel, obținem un lanț de prototipuri - person-employee-manager: employee moștenește prototipul de la person, manager moștenește prototipul de la employee.

Apelarea metodelor din prototipul de bază

Uneori poate fi necesar să apelăm metodele care sunt definite în prototip. Acest lucru poate fi util pentru scurtarea codului și reducerea duplicării, în special atunci când codul unei metode redefinite repetă logica metodei din prototip. Prin obținerea prototipului obiectului, putem apela metodele sale folosind funcția call():

const person = {
   name: "",
   age: 0,  
   print: function(){
       console.log(`Name: ${this.name}  Age: ${this.age}`);
   }
};
// Obiectul "employee" moștenește prototipul obiectului "person"
const employee = Object.create(person);
employee.name = "Tom";
employee.age = 39;
employee.company = "Google";
// Redefinim metoda "print"
employee.print = function(){
   this.__proto__.print.call(this);    // apelăm versiunea metodei din person
   // Object.getPrototypeOf(this).print.call(this);  // variantă alternativă
   console.log(`Company: ${this.company}`);
}

employee.print();   // Name: Tom  Age: 39
                   // Company: Google

În acest caz, în metoda suprascrisă "print" a tipului "employee", apelăm versiunea metodei "print" din "person" folosind prototipul.

Verificarea moștenirii prototipurilor și Object.isPrototypeOf()

Cu ajutorul metodei Object.isPrototypeOf() puteți verifica dacă un obiect este prototipul altui obiect.

const person = {
   name: "",
   print: ()=>console.log("Name:", this.name)
};
const user = {
   name: "",
   print: ()=>console.log("Name:", this.name)
};

// Obiectul "employee" moștenește prototipul obiectului "person".
const employee = Object.create(person);

console.log(person.isPrototypeOf(employee));    // true
console.log(user.isPrototypeOf(employee));      // false

Aici, obiectul "employee" moștenește prototipul de la "person". Prin urmare, apelul person.isPrototypeOf(employee) va returna true. Însă, obiectul "user" nu este prototipul pentru "employee", chiar dacă au aceeași structură de metode și proprietăți.

← Lecția anterioară Lecția următoare →