Prototype և Inheritance JavaScript-ում
JavaScript-ում ժառանգականությունը իրականացվում է prototypal inheritance-ի միջոցով։ Դա նշանակում է, որ օբյեկտները կարող են ժառանգել այլ օբյեկտներից՝ հատուկ հատկությամբ՝ [[Prototype]]։
Սա մի քիչ տարբերվում է դասական OOP լեզուներից (օրինակ՝ Java, C#), որտեղ օգտագործվում են դասեր (classes)։
Ինչ է Prototype-ը
JavaScript-ում յուրաքանչյուր օբյեկտ կարող է ունենալ մեկ այլ օբյեկտ որպես պրոտոտիպ։ Երբ օբյեկտի հատկությունը որոնվում է և չի գտնվում, JavaScript-ը որոնումը փոխանցում է դրա պրոտոտիպին։
const animal = {
eats: true,
};
const dog = {
barks: true,
};
Object.setPrototypeOf(dog, animal);
console.log(dog.eats); // true (ժառանգել է animal-ից)
Այստեղ, dog-ը չունի eats հատկություն, բայց այն ժառանգում է animal-ից։
Հնարավոր է նաև ստեղծել նոր օբյեկտ՝ անմիջապես նշելով պրոտոտիպը՝ Object.create() մեթոդով։
const cat = Object.create(animal);
cat.meows = true;
console.log(cat.eats); // true
console.log(cat.meows); // true
Prototype Chain (Պրոտոտիպների շղթա)
Երբ փնտրում ես հատկություն օբյեկտում, JavaScript-ը որոնում է՝
- Ներկա օբյեկտի մեջ
- Նրա պրոտոտիպում
- Պրոտոտիպի պրոտոտիպում... մինչև հասնի
null
console.log(cat.hasOwnProperty("meows")); // true
console.log(cat.hasOwnProperty("eats")); // true (քո օբյեկտում չկա, բայց ժառանգվել է)
Այս մեխանիզմը կոչվում է prototype chain։
Constructor Function և Prototype
Դու կարող ես ստեղծել կոնստրուկտոր ֆունկցիա, և JavaScript-ը ավտոմատ կապում է նրա prototype հատկությունը ստեղծվող օբյեկտների պրոտոտիպին։
function Person(name) {
this.name = name;
}
Person.prototype.sayHi = function () {
return `Hi, I'm ${this.name}`;
};
const john = new Person("John");
console.log(john.sayHi()); // Hi, I'm John
Ահա ինչ է տեղի ունենում ներքինում՝
- Ստեղծվում է նոր օբյեկտ
- Նրա պրոտոտիպը դառնում է
Person.prototype - Կոնստրուկտորը դիմում է
this-ով կապակցված նոր օբյեկտին
Class syntax-ը (syntactic sugar)
ECMAScript 2015 (ES6)-ից սկսած մենք կարող ենք օգտագործել class սինտաքսը, որը պարզապես sugar է նույն պրոտոտիպային մեխանիզմի վրա։
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound.`;
}
}
class Dog extends Animal {
speak() {
return `${this.name} barks.`;
}
}
const rex = new Dog("Rex");
console.log(rex.speak()); // Rex barks.
Իրականում Dog ժառանգում է Animal-ից, օգտագործելով նույն prototype chain մեխանիզմը։
Որտեղ է օգտագործվում Prototype-ը իրական նախագծերում
- Օբյեկտների վերաօգտագործում / ժառանգում (DRY principle)
- Հատկություններ կամ մեթոդներ կիսելու համար
- Framework-ներում՝ օրինակ React-ի `Component.prototype`, Vue-ի ընդլայնումներում
- Performance-ի բարելավում՝ մեթոդները մեկ վայրում պահելով
Եզրափակում
Prototype համակարգը JavaScript-ի հիմնասյուներից է։ Այն թույլ է տալիս օբյեկտներին ժառանգել իրարից և օգտագործել կոդը չկրկնելու հզոր մոտեցումներ։ Դասական OOP լեզուների համեմատությամբ այն ավելի ճկուն է և դինամիկ։
Դասերի և պրոտոտիպների ճիշտ ըմբռնումը JavaScript-ում տալիս է խոր և վստահ կոդ գրելու կարողություն։