Sobes.tech
Middle

Ce este moștenirea prototipică în JavaScript?

sobes.tech AI

Răspuns de la AI

În JavaScript, obiectele moștenesc proprietăți și metode de la prototipurile lor. Prototipul fiecărui obiect este un alt obiect, ale cărui proprietăți și metode sunt accesibile prin lanțul de prototipuri.

Când se accesează o proprietate a unui obiect, JavaScript o caută mai întâi direct în obiectul respectiv. Dacă proprietatea nu este găsită, căutarea continuă în prototipul acelui obiect, apoi în prototipul prototipului și tot așa, până când proprietatea este găsită sau se ajunge la sfârșitul lanțului (null).

Moștenirea prototipică diferă de moștenirea clasică (cum ar fi în Java sau C++), unde obiectele sunt create din clase care descriu structura și comportamentul lor. În JavaScript, clasele, introduse în ES6, sunt un zahăr sintactic peste moștenirea prototipică.

Aspecte principale:

  • __proto__: Proprietate internă a obiectului care face referire la prototipul său.
  • prototype: Proprietate a constructorului (funcție folosită ca și constructor), care face referire la obiectul care va servi drept prototip pentru instanțele create.
  • Object.getPrototypeOf(obj): Metodă standard pentru a obține prototipul unui obiect.
  • Object.setPrototypeOf(obj, proto): Metodă standard pentru a seta prototipul unui obiect.

Exemplu:

// Funcție constructor
function Animal(name) {
  this.name = name;
}

// Adăugăm metodă în prototipul Animal
Animal.prototype.sayHello = function() {
  console.log(`Salut, numele meu este ${this.name}`);
};

// Creăm o instanță
const dog = new Animal("Buddy");

// Apelăm metoda din prototip
dog.sayHello(); // Afișează: Salut, numele meu este Buddy

// Prototipul lui dog este Animal.prototype
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true

// Prototipul lui Animal.prototype este Object.prototype
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // true

// Sfârșitul lanțului de prototipuri este null
console.log(Object.getPrototypeOf(Object.prototype) === null); // true

Comparativ cu moștenirea clasică (folosind clase ES6):

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

  sayHello() {
    console.log(`Salut, numele meu este ${this.name}`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Apelarea constructorului clasei părinte
    this.breed = breed;
  }

  bark() {
    console.log("Woof!");
  }
}

const buddy = new Dog("Buddy", "Golden Retriever");
buddy.sayHello(); // Afișează: Salut, numele meu este Buddy (moștenit de la Animal)
buddy.bark(); // Afișează: Woof! (metoda Dog)

// Clasele în ES6 sunt zahăr sintactic peste prototipuri
console.log(Object.getPrototypeOf(Dog) === Animal); // true (moștenire de clase)
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true (moștenire de metode prin prototipuri)
console.log(Object.getPrototypeOf(buddy) === Dog.prototype); // true (instanța moștenește de la prototipul clasei)

Moștenirea prototipică este un concept cheie în JavaScript, iar înțelegerea sa este esențială pentru a lucra eficient cu limbajul.