Sobes.tech
Junior

Paaiškinkite, kaip veikia paveldėjimas JavaScript.

sobes.tech AI

Atsakymas iš AI

JavaScript-ში მემკვიდრეობა რეალიზებულია პროტოტიპების მეშვეობით. თითოეულ ობიექტს JavaScript-ში აქვს შიდა მახასიათებელი [[Prototype]], რომელიც მიუთითებს სხვა ობიექტზე. როდესაც ჩვენ ვცდილობთ მივიღოთ წვდომა ობიექტის თვისებაზე ან მეთოდზე, რომელიც პირდაპირ არ არის მასზე, JavaScript-ის ძრავი ეძებს ამ თვისებას ან მეთოდს ამ ობიექტის პროტოტიპში. თუ ის იქ ვერ მოიძებნება, ძრავი აგრძელებს ძიებას პროტოტიპების ჯაჭვში, რომელიც შედგება [[Prototype]] კავშირებისგან, სანამ არ მიაღწევს null-ს (ჯაჭვის ბოლომდე).

არსებობს ორი ძირითადი მემკვიდრეობის მექანიზმი:

  1. კლასიკური პროტოტიპული მემკვიდრეობა (ES5 და ადრეული): დაფუძნებულია ფუნქციების კონსტრუქტორების გამოყენებაზე და მათი prototype თვისებაზე.

    // კონსტრუქტორის ფუნქცია
    function Animal(name) {
      this.name = name;
    }
    
    // მეთოდის დამატება პროტოტიპში
    Animal.prototype.speak = function() {
      console.log(`${this.name} ხმას გამოსცემს.`);
    };
    
    // ობიექტის შექმნა
    const dog = new Animal('ძაღლი');
    
    // პროტოტიპის მეთოდის გამოძახება
    dog.speak(); // გამოიტანს: ძაღლი ხმას გამოსცემს.
    
    // პროტოტიპი - ეს არის Animal.prototype
    console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true
    
  2. კლასური მემკვიდრეობა (ES6 და შემდგომ): იყენებს სინტაქსურ შაქარს class და extends, რომელიც ქვემოთ მაინც მუშაობს პროტოტიპებზე.

    // ძირითადი კლასი
    class Animal {
      constructor(name) {
        this.name = name;
      }
    
      speak() {
        console.log(`${this.name} ხმას გამოსცემს.`);
      }
    }
    
    // შვილობილი კლასი, რომელიც მემკვიდრეობს Animal-დან
    class Dog extends Animal {
      constructor(name, breeds) {
        super(name); // მშობლის კონსტრუქტორის გამოძახება
        this.breeds = breeds;
      }
    
      bark() {
        console.log(`${this.name} ყეფს.`);
      }
    }
    
    // შვილობილი კლასი ობიექტის შექმნა
    const myDog = new Dog('ბუბული', ['ლაბრადორი', 'კოლლი']);
    
    // მეთოდების გამოძახება როგორც Animal-დან, ასევე Dog-დან
    myDog.speak(); // გამოიტანს: ბუბული ხმას გამოსცემს.
    myDog.bark();  // გამოიტანს: ბუბული ყეფს.
    
    // myDog-ის პროტოტიპი - ეს არის Dog.prototype
    console.log(Object.getPrototypeOf(myDog) === Dog.prototype); // true
    
    // Dog.prototype-ის პროტოტიპი - ეს არის Animal.prototype
    console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
    

ძირითადი კონცეფციები:

  • პროტოტიპული ჯაჭვი: კავშირი ობიექტებს შორის მათი [[Prototype]]-ის საშუალებით.

  • __proto__ (ძველი/არასამართლებადი, მაგრამ სასარგებლო გასაგებად): თვისება, რომლის მეშვეობითაც შესაძლებელია მიეღოს [[Prototype]]. არ არის რეკომენდებული გამოყენება პროდაქშენ კოდში.

  • Object.getPrototypeOf(obj): სტანდარტული მეთოდი ობიექტის პროტოტიპის მისაღებად.

  • Object.setPrototypeOf(obj, proto): სტანდარტული მეთოდი ობიექტის პროტოტიპის შეცვლისთვის (არ არის რეკომენდებული უკვე შექმნილი ობიექტების პროტოტიპის შეცვლისთვის).

  • instanceof: ოპერაცია, რომელიც ამოწმებს, არის თუ არა ობიექტი კლასის ან კონსტრუქტორის ფუნქციის ინstanzა, მისი პროტოტიპული ჯაჭვის შემოწმებით.

    console.log(myDog instanceof Dog);   // true
    console.log(myDog instanceof Animal); // true
    console.log(myDog instanceof Object); // true (ბოლოს Object.prototype)
    
  • super: გამოიყენება კლასებში მშობლის მეთოდების ან კონსტრუქტორის გამოძახებისთვის.

კლასიკური და კლასური მიდგომების განსხვავება: კლასები უზრუნველყოფს უფრო სტრუქტურირებულ და სინტაქსურად მოსახერხებელ გზას პროტოტიპული მემკვიდრეობის მუშაობისთვის, რაც მსგავსია სხვა პროგრამირების ენებთან. თუმცა ძირითადი მექანიზმი იგივე რჩება — მემკვიდრეობა პროტოტიპების მეშვეობით.