Prototype merosxo'rligi haqida tushuncha (Prototype Inheritance)

JavaScriptdagi prototype merosxo'rligi haqida hamda, qanday ishlashi va amaliy qo'llanilishi.

So'nggi yangilanish: 2024-12-11

Prototype merosxo'rligi haqida tushuncha (Prototype Inheritance)

JavaScript - bu prototype asosli, obyektga yo'naltirilgan dasturlash tili. Class asosli tillardan farqli ravishda, JavaScriptdagi merosxo'rlik prototiplarga asoslanadi. Ushbu hujjatda prototype merosxo'rligini to'liq tushuntirish, uning mexanizmlari va amaliy qo'llanilishi ko'rib chiqiladi.

Prototype nima?

JavaScriptda har bir obyektda [[Prototype]] deb nomlanuvchi ichki xususiyat mavjud bo'lib, u boshqa obyektga havola hisoblanadi. Ushbu prototip obyekti boshqa obyektlarning xususiyatlari va metodlarini meros qilib olish uchun andoza sifatida ishlashi mumkin. Bu esa obyektlarni qayta ishlatish va xotirani samarali foydalanishni ta'minlaydi.

Obyektning prototipiga quyidagicha murojaat qilish mumkin:

  • Object.getPrototypeOf(obj) metodi orqali.
  • Eskirgan __proto__ xususiyati orqali (zamonaviy kodda tavsiya etilmaydi).
  • Konstruktor funksiyalar uchun prototype xususiyati orqali.

Prototype zanjiri

Prototype zanjiri obyektlar orasidagi bog'lanishlar qatoridan iborat. Agar xususiyat yoki metod joriy obyektda topilmasa, JavaScript uni obyektning prototipida izlaydi. Bu jarayon xususiyat topilgunga qadar yoki zanjir oxiriga (null) yetgunga qadar davom etadi.

Misol:

const obj = {};
console.log(obj.toString()); // Object.prototype dan meros qilib olingan

Ushbu misolda, toString() obj obyektida mavjud emas, shuning uchun JavaScript uni Object.prototypedan qidiradi.


Prototiplarni yaratish va ishlatish

Obyekt literalidan foydalanish

Obyekt literalari tabiiy ravishda Object.prototype bilan bog'lanadi.

const person = { // Obyekt literal
  greet() {
    console.log("Salom!");
  }
};
person.greet(); // `Object.prototype` dan meros qilib olingan

Konstruktor funksiyalaridan foydalanish

Konstruktor funksiyalari bir xil prototipga ega obyektlarni yaratadi.

function Person(name) { 
  this.name = name;  // Obyektning xususiyati
}

Person.prototype.greet = function() { // Prototipda metod
  console.log(`Salom, mening ismim ${this.name}`);
};

const john = new Person("John"); 
john.greet(); // `Person.prototype` dan meros qilib olingan

Object.create() dan foydalanish

Object.create() ma'lum bir prototipga ega obyektlarni yaratish imkonini beradi.

const animal = {
  speak() {
    console.log("Men ovoz chiqaraman.");
  }
};

const dog = Object.create(animal);
dog.speak(); // `animal` dan meros qilib olingan

Xususiyatlarni izlash va ustunlik qilish

Xususiyatga murojaat qilinganda:

  1. JavaScript xususiyatni obyektning o'zida qidiradi.
  2. Agar topilmasa, prototip zanjirida qidiradi.

Agar xususiyat obyektning o'zida va prototipida mavjud bo'lsa, obyektning o'zidagi xususiyat ustunlik qiladi.

Misol:

const parent = { name: "Parent" };
const child = Object.create(parent);
child.name = "Child";

console.log(child.name); // "Child"

Prototiplarni o'zgartirish

Prototipga xususiyatlar va metodlarni dinamik ravishda qo'shish yoki o'zgartirish mumkin.

Misol:

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Salom, ${this.name}!`);
};

const alice = new Person("Alice");
alice.greet();

Person.prototype.greet = function() { 
  console.log(`Salomlar, ${this.name}.`);
};
alice.greet();

6. ES6 Classlari va prototiplar

ES6 class sintaksisi prototype asosli merosxo'rlik uchun sintaktik qulaylik sifatida kiritilgan. Aslida, classlar ham prototiplardan foydalanadi.

Misol:

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

  speak() { // Metod
    console.log(`${this.name} tovush chiqarmoqda.`);
  }
}

class Dog extends Animal { // Merosxo'rlik (extends)
  speak() { // Metod
    console.log(`${this.name} vovillamoqda.`);
  }
}

const dog = new Dog("Buddy"); // Instance
dog.speak();

Prototype merosxo'rligiga amaliy misollar

Misol 1: Metodlarni bo'lishish

function Car(brand) {
  this.brand = brand;
}

Car.prototype.drive = function() {
  console.log(`${this.brand} haydab bormoqda.`);
};

const tesla = new Car("Tesla");
tesla.drive();

Misol 2: Ichki obyektlarni kengaytirish

Array.prototype.first = function() { // Array prototipini kengaytirish
  return this[0]; // Birinchi elementni qaytarish
};

const numbers = [1, 2, 3];
console.log(numbers.first()); // 1

Afzalliklar va kamchiliklar

Afzalliklar

  • Xotirani tejash orqali metodlarni umumiy qilish.
  • Dinamik merosxo'rlikni runtime da o'zgartirish imkoniyati.
  • Turli xil yaratish uslublarida (methods) moslashuvchanlik.

Kamchiliklar

  • Prototype zanjirining murakkabligi sababli debugging qiyin.
  • Zanjir (chain) chuqurligi katta bo'lsa, samaradorlikka ta'sir qilishi mumkin.
  • Keraksiz xususiyatlarning prototipdan meros qilib olinishi.

Eng yaxshi amaliyotlar

  • Object.prototype kabi ichki prototiplarni o'zgartirmaslik.
  • Toza merosxo'rlik uchun Object.create() dan foydalanish.
  • O'qilishi va texnik xizmat ko'rsatishda qulaylik uchun ES6 class sintaksisini afzal ko'rish.
  • Faqat o'ziga tegishli xususiyatlarni tekshirish uchun hasOwnProperty dan foydalanish.

Misol:

console.log(obj.hasOwnProperty("toString")); // false

Qo'shimcha Manbalar

  1. MDN Web Docs: Prototypes
  2. Eloquent JavaScript: Prototypes
  3. JavaScript.info: Prototypes
  4. You Don’t Know JS: Objects & Prototypes