Sobes.tech
Junior

Ներկայացրեք, թե ինչպես է աշխատում ժառանգությունը JavaScript-ում։

sobes.tech AI

Պատասխան AI-ից

JavaScript- ում ժառանգությունը իրականացվում է պրոտոտիպների միջոցով: Յուրաքանչյուր օբյեկտ JavaScript- ում ունի ներքին հատկություն [[Prototype]], որը հղում է մյուս օբեկտին: Երբ մենք փորձում ենք մուտք գործել օբյեկտի հատկություն կամ մեթոդ, որը անմիջապես նրա մեջ չի, JavaScript շարժիչը որոնում է այդ հատկությունը կամ մեթոդը այդ օբյեկտի պրոտոտիպում: Եթե այն այնտեղ չի գտնում, որոնումը շարունակվում է պրոտոտիպների շղթայով, որը ձևավորվում է [[Prototype]] կապերով, մինչև հասնի null (շղթայի վերջը):

Կան երկու հիմնական ժառանգության մեխանիզմներ:

  1. Կլասիկ պրոտոտիպային ժառանգություն (ES5 և ավելի վաղ): հիմնված է կոնստրուկտորային ֆունկցիաների և դրանց prototype հատկության օգտագործման վրա:

    // Կոնստրուկտորային ֆունկցիա
    function Կենդանի(անուն) {
      this.անուն = անուն;
    }
    
    // Մեթոդ ավելացնել պրոտոտիպին
    Կենդանի.prototype.խոսել = function() {
      console.log(`${this.անուն} ձայն է հանում.`);
    };
    
    // Օբյեկտի ստեղծում
    const շուն = new Կենդանի('Շուն');
    
    // Մեթոդի կանչ պրոտոտիպից
    շուն.խոսել(); // Արտածում: Շուն ձայն է հանում.
    
    // `dog` պրոտոտիպը `Կենդանի.prototype` է
    console.log(Object.getPrototypeOf(շուն) === Կենդանի.prototype); // true
    
  2. Կլասային ժառանգություն (ES6 և ավելի նոր): օգտագործում է class և extends սինտաքսը, որը ներքո աշխատում է պրոտոտիպների հետ:

    // Հիմնական դասը
    class Կենդանի {
      constructor(անուն) {
        this.անուն = անուն;
      }
    
      խոսել() {
        console.log(`${this.անուն} ձայն է հանում.`);
      }
    }
    
    // Դուստր դաս, ժառանգում է Կենդանի-ից
    class Շուն extends Կենդանի {
      constructor(անուն, ցեղեր) {
        super(անուն); // Հիշեցում՝ ծնողի կոնստրուկտոր
        this.ցեղեր = ցեղեր;
      }
    
      հաչել() {
        console.log(`${this.անուն} հաչում է.`);
      }
    }
    
    // Օբյեկտի ստեղծում
    const իմՇուն = new Շուն('Bublik', ['Labrador', 'Collie']);
    
    // Մեթոդների կանչ երկու դասից
    իմՇուն.խոսել(); // Արտածում: Bublik ձայն է հանում.
    իմՇուն.հաչել();  // Արտածում: Bublik հաչում է.
    
    // `Շուն.prototype` պրոտոտիպը `Կենդանի.prototype` է
    console.log(Object.getPrototypeOf(իմՇուն) === Շուն.prototype); // true
    
    // `Շուն.prototype` պրոտոտիպը `Կենդանի.prototype` է
    console.log(Object.getPrototypeOf(Շուն.prototype) === Կենդանի.prototype); // true
    

Հիմնական հասկացություններ՝

  • Պրոտոտիպների շղթա: Կապը օբյեկտների միջև [[Prototype]]-ի միջոցով:

  • __proto__ (հնացած/չստանդարտ, բայց օգտակար հասկանալու համար): Գործառույթ, որով կարելի է հասանելիություն ունենալ [[Prototype]]-ին: Չի խորհուրդ տրվում օգտագործել արտադրական կոդում:

  • Object.getPrototypeOf(obj): Ստանդարտ միջոց՝ ստանալու օբյեկտի պրոտոտիպը:

  • Object.setPrototypeOf(obj, proto): Ստանդարտ միջոց՝ փոփոխելու օբյեկտի պրոտոտիպը (չի խորհուրդ տրվում փոփոխել արդեն գոյություն ունեցող օբյեկտների պրոտոտիպները ստեղծելուց հետո):

  • instanceof: Օպերատոր՝ ստուգելու համար, արդյոք օբյեկտը դասի կամ կոնստրուկտորային ֆունկցիայի օրինակ է, պրոտոտիպ շղթայի միջոցով:

    console.log(իմՇուն instanceof Շուն);   // true
    console.log(իմՇուն instanceof Կենդանի); // true
    console.log(իմՇուն instanceof Object); // true (շղթայի վերջում `Object.prototype`)
    
  • super: Օգտագործվում է դասերում՝ հղում կատարելու համար ծնողական դասի մեթոդներին կամ կոնստրուկտորին:

Հիմնական տարբերությունը՝ դասական և դասային մոտեցումներում՝: Դասերը ավելի կառուցվածքային և սինտակսապես հարմարավետ միջոց են պրոտոտիպային ժառանգությունը աշխատելու համար, մոտեցում՝ ինչպես մյուս ծրագրավորման լեզուներում: Սակայն հիմնական մեխանիզմը մնում է նույնը՝ ժառանգությունը պրոտոտիպների միջոցով։