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'shiladiPerson.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.