Series: JavaScript Basics Lesson 29

Static Method

Static metod oddiy metoddan qanday farq qiladi, V8 ichida qayerda saqlanadi, factory pattern, static ichida this va static metodlarning meros olinishi.

29-dars

Static Method

1. Static method nima — oddiy metoddan farqi

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

  greet() { // ODDIY metod — Person.prototype'ga qo'shiladi
    return `Salom, men ${this.name}`;
  }

  static create(name) { // STATIC metod — Person'ning O'ZIGA qo'shiladi
    return new Person(name);
  }
}

Asosiy farq: oddiy metod (greet) — Person.prototypega qo'shiladi va instance orqali chaqiriladi. static metod (create) — Personning o'ziga (funksiya-obyektga) to'g'ridan-to'g'ri qo'shiladi va class nomi orqali, instance yaratmasdan chaqiriladi.

const p1 = Person.create('Ali'); // ✅ to'g'ri — class orqali
const p2 = p1.create('Vali');    // ❌ TypeError: p1.create is not a function

2. V8 ichida qayerda saqlanadi — aniq joylashuv

console.log(typeof Person.create);           // 'function' — Person'NING O'ZIDA
console.log(Person.prototype.create);         // undefined — prototype'da YO'Q!
console.log(typeof Person.prototype.greet);   // 'function' — prototype'da BOR
console.log(Person.greet);                    // undefined — Person'ning o'zida YO'Q!

Xotira tuzilishi:

HEAP:
Person (function object)
  ├── create: fn         ← STATIC metod, to'g'ridan-to'g'ri shu yerda
  ├── prototype ────────→ Person.prototype { greet: fn, constructor→Person }
  └── [[Prototype]] ────→ Function.prototype

Ya'ni ikkita butunlay alohida joy bor:

  • Person (funksiya-obyektning o'zi) — static metodlar shu yerga qo'shiladi
  • Person.prototype — oddiy (instance) metodlar shu yerga qo'shiladi

Bular — bir-biridan mustaqil, bog'liq bo'lmagan ikki xil obyekt. Shu sababli instance (p1) hech qachon static metodga prototype chain orqali yetib bora olmaydi — chunki p1.[[Prototype]] faqat Person.prototypega ishora qiladi, Personning o'ziga emas.

p1.[[Prototype]] → Person.prototype → Object.prototype → null
                         ↑
                    static metodlar BU YERDA YO'Q,
                    ular Person'ning o'zida (yuqorida, alohida)

3. Constructor function bilan — staticning "eski" yozilishi

Class'dan oldin, xuddi shu narsa qo'lda yozilardi:

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

Person.prototype.greet = function() {
  return `Salom, men ${this.name}`;
};

Person.create = function(name) { // TO'G'RIDAN-TO'G'RI Person'ga qo'shildi — bu "static"
  return new Person(name);
};
const p1 = Person.create('Ali'); // ishlaydi, xuddi class'dagidek

Bu — isbot: static — yangi mexanizm emas, balki class'ning syntactic sugari orqali avtomatik bajariladigan, allaqachon mavjud bo'lgan mexanizm (funksiyaga to'g'ridan-to'g'ri property qo'shish).


4. Nega static metod kerak — amaliy holatlar

A) Factory metodlar (obyekt yaratish logikasi)

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  static fromJSON(json) {
    const data = JSON.parse(json);
    return new Person(data.name, data.age);
  }
}

const p1 = Person.fromJSON('{"name":"Ali","age":25}');

fromJSON — bu instance metodiga aylanishi mantiqan noto'g'ri, chunki uni chaqirish uchun hali instance yo'q (aynan instance yaratish uchun chaqirilyapti). Shuning uchun static — bunday "instance yaratishdan oldingi" logika uchun tabiiy joy.

B) Utility/helper metodlar (instance ma'lumotiga bog'liq emas)

class MathHelper {
  static square(x) {
    return x * x;
  }
  static cube(x) {
    return x * x * x;
  }
}

MathHelper.square(5); // 25 — instance kerak emas

this.name kabi instance-specific ma'lumot ishlatilmaydigan hisob-kitob funksiyalar uchun static — mantiqan to'g'ri, chunki har safar new MathHelper() qilib instance yaratish behuda bo'lardi.

C) Instance-larni sanash (barcha instance uchun umumiy holat)

class Person {
  static count = 0; // STATIC PROPERTY — barcha instance uchun BITTA, umumiy

  constructor(name) {
    this.name = name;
    Person.count++; // static property'ni yangilash
  }
}

new Person('Ali');
new Person('Vali');
console.log(Person.count); // 2

Bu — static metod bilan bir xil joyda (Personning o'zida) yashovchi static property. Instance'lar (this.name) har biri o'z alohida qiymatiga ega, lekin Person.count — barcha instance'lar uchun bitta, umumiy qiymat.


5. Static metod ichida this — nimaga teng?

class Person {
  static create(name) {
    console.log(this); // Person (class'ning O'ZI, instance emas!)
    return new this(name); // 'new Person(name)' bilan BIR XIL
  }
}

Static metod ichida this — class'ning o'zi (Person), instance emas. Bu — juda foydali, chunki inheritance bilan birga ishlatilganda, this avtomatik to'g'ri subclass'ga ishora qiladi:

class Person {
  static create(name) {
    return new this(name); // 'this' — chaqirilgan klassga qarab o'zgaradi
  }
}

class Student extends Person {}

const s1 = Student.create('Ali'); // this === Student (Person emas!)
console.log(s1 instanceof Student); // true
console.log(s1 instanceof Person);  // true

Agar new Person(name) deb qattiq yozilganida, Student.create() chaqirilsa ham, natija doim Person instance bo'lib qolardi (Student emas). new this(name) — bu muammoni hal qiladi, chunki this chaqiruv kontekstiga qarab to'g'ri klassni oladi.


6. Static metodlar ham meros olinadimi?

class Animal {
  static create(name) {
    return new this(name);
  }
}

class Dog extends Animal {}

const d1 = Dog.create('Rex'); // ✅ ISHLAYDI! static metod ham meros olindi
console.log(d1 instanceof Dog); // true

Ha! Static metodlar ham prototype chain'ga o'xshash mexanizm orqali meros olinadi — lekin bu oddiy Dog.prototype → Animal.prototype zanjiri emas, balki Dog → Animal (funksiya-obyektlarning o'zi orasidagi) alohida zanjir:

console.log(Object.getPrototypeOf(Dog) === Animal); // true!

class extends ikkita parallel zanjir yaratadi:

INSTANCE ZANJIRI:          d1 → Dog.prototype → Animal.prototype → Object.prototype → null
STATIC (FUNCTION) ZANJIRI:  Dog → Animal → Function.prototype → Object.prototype → null

Ya'ni Dogning o'zi ham, o'z navbatida, Animalga [[Prototype]] orqali ulangan — shu sababli static metodlar ham xuddi instance metodlar kabi, qidiruv orqali meros olinadi.


7. Static getter/setter — bor, xuddi instance'dagidek

class Config {
  static #instance; // private static field

  static get instance() {
    if (!Config.#instance) {
      Config.#instance = new Config();
    }
    return Config.#instance;
  }
}

const c1 = Config.instance; // getter chaqiriladi

Bu — Singleton patternning klassik namunasi, static getter orqali amalga oshiriladi.


8. Xulosa — jadval bilan solishtirish

Oddiy (instance) metod Static metod
Qayerga qo'shiladi Class.prototype Class (funksiyaning o'ziga)
Qanday chaqiriladi instance.method() Class.method()
Ichidagi this Instance'ning o'zi Class'ning o'zi
Instance orqali chaqirish ✅ Ishlaydi ❌ TypeError
Meros olinadimi ✅ Ha (Dog.prototype → Animal.prototype) ✅ Ha (Dog → Animal)
Amaliy ishlatilishi Instance ma'lumoti bilan ishlash (this.name) Factory, utility, umumiy holat (count)

Xulosa

Static metod — Class.prototypega emas, Classning o'ziga (funksiya-obyektga) to'g'ridan-to'g'ri qo'shiladigan metod; u instance orqali emas, faqat class nomi orqali chaqiriladi, ichida this — class'ning o'zini bildiradi, va u ham (parallel, alohida Class → ParentClass zanjiri orqali) meros olinadi.