Mundarija (34)
- Bu darsda
- 1. Nega bu kerak?
- 2. Birinchi maydonlar
- 2.1 Sintaksis
- 2.2 Qiymatsiz maydon
- 2.3 Har nusxaga — o'z qiymati
- 3. Initializer tartibi
- 3.1 Maydonlar constructor dan oldin
- 3.2 Initializer ichida this
- 3.3 Initializer constructor parametrlarini ko'rmaydi
- 3.4 Initializer — istalgan ifoda
- 4. Nima maydonga, nima constructor ga?
- 4.1 Klassdan tashqarida xususiyat qo'shish
- 4.2 Hisoblangan maydon nomi
- 5. Arrow maydon va this
- 5.1 Muammo: metodni tinglovchiga berish
- 5.2 Yechim: arrow funksiya maydonda
- 5.3 Narxi
- 5.4 Uchta yo'lni solishtiramiz
- 6. Brauzerlarda qo'llab-quvvatlanishi
- 7. Ko'p uchraydigan xatolar
- 7.1 Obyekt literalidagi kabi ikki nuqta
- 7.2 Maydon oldida let yoki const
- 7.3 Metodda this. siz maydon
- 7.4 Initializer'da constructor parametri
- 7.5 Maydonlar tartibi
- 8. Mashqlar
- 1-mashq (oson): Stol klassi
- 2-mashq (o'rta): Tartibni oldindan ayting
- 3-mashq (qiyin): Arrow maydon qachon kerak?
- 4-mashq: Vazifalar qadami — Vazifa ning pasporti
- 9. Real ishda
- Xulosa
- Manbalar
JavaScript class maydonlari (fields): xususiyatni konstruktorsiz e'lon qilish
Qisqacha: Klass maydoni (class field) — klass tanasida,
constructordan tashqarida e'lon qilingan xususiyat:taomlar = [];. U har nusxaning o'z xususiyatiga aylanadi vaconstructortanasidan oldin yuqoridan pastga ishga tushadi. Maydon qiymati arrow funksiya bo'lsa (oshir = () => {...}),thisdoim nusxaga bog'langan bo'ladi — lekin har nusxa funksiyaning o'z nusxasini oladi.
Bu darsda
- Klass maydonlarini boshlang'ich qiymat bilan va qiymatsiz e'lon qila olasiz.
- Maydonlar va
constructorqaysi tartibda ishlashini tushuntira olasiz. - Nima maydonga, nima
constructorga yozilishini tanlay olasiz. - Arrow maydon bilan
thisyo'qolishini hal qilasiz va bu yechimning narxini bilasiz. vazifalardagiVazifaklassiga maydonlar ro'yxatini qo'shasiz.
Oldin bilishingiz kerak: class sintaksisi, this yo'qolishi va uni tiklash, Function expression va arrow funksiyalar.
1. Nega bu kerak?
class sintaksisi darsida hamma xususiyat constructor ichida yozildi. Restoran buyurtmasi uchun klass:
class Buyurtma {
constructor(stol) {
this.stol = stol;
this.taomlar = [];
this.holat = "yangi";
this.izoh = "";
}
}
console.log(new Buyurtma(5));Konsolda:
Buyurtma { stol: 5, taomlar: [], holat: 'yangi', izoh: '' }To'rtta qatordan faqat bittasi — stol — tashqaridan keladi. Qolgan uchtasi har buyurtmada bir xil boshlanadi: bo'sh ro'yxat, "yangi" holat, bo'sh izoh. Ular argumentga bog'liq emas, lekin baribir konstruktor ichida, this. bilan yozilishi kerak. Klass kattalashsa, konstruktor o'nlab shunday qatorlarga to'ladi va "bu klassda qanday xususiyatlar bor?" degan savolga javob topish qiyinlashadi.
Klass maydonlari bu savolga birinchi qatorlardayoq javob beradi. 09-qismdagi Savat klassida taomlar = []; qatorini ko'rgan edik va uni "keyingi darsda" deb qoldirgan edik (class sintaksisi). Bugun shu qator.
Hayotdan o'xshatish: yangi xodimga beriladigan anketa. Unda "Ism: ___" kabi bo'sh joylar bor — ularni xodim to'ldiradi. "Lavozim: stajyor", "Oylik: sinov davri" esa allaqachon yozilgan — hamma uchun bir xil. Maydon — anketaning oldindan bosilgan qismi, constructor — xodim to'ldiradigan qismi.
2. Birinchi maydonlar
2.1 Sintaksis
Xuddi o'sha Buyurtma, maydonlar bilan:
class Buyurtma {
taomlar = [];
holat = "yangi";
izoh = "";
constructor(stol) {
this.stol = stol;
}
}
console.log(new Buyurtma(5));Konsolda:
Buyurtma { taomlar: [], holat: 'yangi', izoh: '', stol: 5 }Qoidalar:
- Maydon —
nom = qiymat;. Oldidathis.ham,let/constham yo'q. - Har maydon oxirida nuqtali vergul — oddiy ko'rsatma kabi.
- Natija bir xil: har nusxada o'sha to'rt xususiyat. Faqat tartib o'zgardi — maydonlar
stoldan oldin chiqdi.
Initializer — maydondagi = dan keyingi ifoda ([], "yangi"). Inglizcha "initialize" — "boshlang'ich qiymat bermoq". Anketa o'xshatishida — oldindan bosilgan "stajyor" so'zi. Tartib nega o'zgarganini «Initializer tartibi» bo'limida ko'ramiz.
2.2 Qiymatsiz maydon
Maydonni qiymatsiz ham e'lon qilish mumkin:
class Mehmon {
ism;
telefon;
stol = null;
}
console.log(new Mehmon());Konsolda:
Mehmon { ism: undefined, telefon: undefined, stol: null }Qiymatsiz maydon undefined bo'ladi, lekin xususiyat sifatida mavjud: Object.hasOwn(mehmon, "ism") — true. Bu bilan klass tepasida "nusxada qanday xususiyatlar bo'ladi" degan to'liq ro'yxat paydo bo'ladi, qiymatini esa keyin constructor yoki metod beradi.
2.3 Har nusxaga — o'z qiymati
Initializer har new da qaytadan hisoblanadi. Shuning uchun taomlar = [] har buyurtmaga alohida massiv beradi:
class Buyurtma {
taomlar = [];
constructor(stol) {
this.stol = stol;
}
}
const birinchi = new Buyurtma(5);
const ikkinchi = new Buyurtma(7);
birinchi.taomlar.push("osh");
console.log(birinchi.taomlar, ikkinchi.taomlar); // [ 'osh' ] []
console.log(Object.hasOwn(birinchi, "taomlar")); // trueObject.create darsining «Prototipdagi massivni o'zimniki deb o'zgartirish» xatosini eslang: massiv prototipda bo'lsa, hamma nusxa bitta massivni bo'lishadi. Maydon esa xususiyatni prototipga emas, har nusxaning o'ziga qo'yadi. O'sha xato bu yerda yo'q.
Tekshirib ko'ring:
Object.hasOwn(Buyurtma.prototype, "taomlar")nima qaytaradi?
Javob
false. Maydonlar prototipda emas — har nusxada. Prototipda faqat metodlar va constructor bor. Maydon e'loni — "har nusxaga shu xususiyatni qo'y" degan ko'rsatma, prototipga yozish emas.
3. Initializer tartibi
3.1 Maydonlar constructor dan oldin
Kim qachon ishlashini ko'rish uchun har qadamda konsolga yozadigan kichik funksiya ishlatamiz:
function yoz(matn) {
console.log(matn);
return matn;
}
class Tartib {
a = yoz("1: a maydoni");
constructor() {
yoz("3: constructor tanasi");
}
b = yoz("2: b maydoni");
}
new Tartib();Konsolda:
1: a maydoni
2: b maydoni
3: constructor tanasib kodda constructor dan pastda yozilgan, lekin undan oldin ishladi. Qoida: new bo'sh obyektni yaratgach, avval barcha maydonlar yuqoridan pastga ishga tushadi, keyin constructor tanasi. Shuning uchun constructor ichida maydonlarning qiymati allaqachon tayyor bo'ladi.
Keyingi tugmasi bilan new Buyurtma(5) ni kuzating:
3.2 Initializer ichida this
Initializer ichida this — yaratilayotgan nusxa. Demak maydon o'zidan oldingi maydonga tayanishi mumkin:
class Taom {
narx = 30000;
qqs = this.narx * 0.12;
}
console.log(new Taom()); // Taom { narx: 30000, qqs: 3600 }Tartib almashsa — natija buziladi, lekin xato chiqmaydi:
class Taom {
qqs = this.narx * 0.12;
narx = 30000;
}
console.log(new Taom()); // Taom { qqs: NaN, narx: 30000 }qqs hisoblanganda narx hali yo'q — undefined * 0.12 — NaN (NaN). Maydonlar yuqoridan pastga ishlaydi; bir-biriga tayanadigan maydonlarni to'g'ri tartibda yozing.
3.3 Initializer constructor parametrlarini ko'rmaydi
Maydon constructor dan oldin ishlaydi — demak uning parametrlarini ham bilmaydi:
class Taom {
qqs = narx * 0.12;
constructor(narx) {
this.narx = narx;
}
}
new Taom(30000);ReferenceError: narx is not definedTarjimasi: "narx aniqlanmagan". narx — constructor ning parametri, u faqat konstruktor ichida yashaydi (Scope asoslari). Initializer esa klass tanasining scope'ida. Tuzatish: argumentga bog'liq qiymatni constructor ichida hisoblang: this.qqs = narx * 0.12.
Tekshirib ko'ring: Quyidagi klassdan
new Hisob(10)qanday obyekt beradi?class Hisob { soni = 1; constructor(boshi) { this.soni = this.soni + boshi; } }
Javob
Hisob { soni: 11 }. Avval maydon: soni = 1. Keyin constructor: this.soni allaqachon 1, unga 10 qo'shiladi. Maydon — boshlang'ich qiymat, constructor uni o'zgartirishi mumkin.
3.4 Initializer — istalgan ifoda
Initializer faqat tayyor qiymat emas, istalgan ifoda bo'lishi mumkin — funksiya chaqiruvi ham. Closure amaliyotda darsidagi hisoblagich bilan har buyurtmaga avtomatik raqam beramiz:
function hisoblagichYasa() {
let soni = 0;
return () => ++soni;
}
const keyingiRaqam = hisoblagichYasa();
class Buyurtma {
raqam = keyingiRaqam();
vaqt = "12:30";
}
console.log(new Buyurtma().raqam); // 1
console.log(new Buyurtma().raqam); // 2keyingiRaqam() har new da qaytadan chaqirildi — chunki initializer har nusxa uchun alohida hisoblanadi. Agar maydon qiymati bir marta, klass e'lon qilinganda hisoblanganida edi, ikkala buyurtma ham 1 raqamini olardi. «Har nusxaga — o'z qiymati» bo'limidagi [] bilan bir xil qoida.
Lekin initializer'ni og'irlashtirmang. Unda bir-ikki qatorli hisob, funksiya chaqiruvi — yaxshi. Shartlar, sikllar, bir nechta qadam kerak bo'lsa — ularni constructor ga yoki alohida metodga chiqaring. Maydonlar ro'yxati "pasport" bo'lib qolsin, mantiq esa o'zi uchun mo'ljallangan joyda tursin.
4. Nima maydonga, nima constructor ga?
Oddiy qoida:
| Qiymat qayerdan keladi? | Qayerga yoziladi | Misol |
|---|---|---|
| Har nusxada bir xil boshlanadi | maydon, initializer bilan | taomlar = [], holat = "yangi" |
| Tashqaridan, argument bilan | constructor da |
this.stol = stol |
| Argumentdan hisoblanadi | constructor da |
this.qqs = narx * 0.12 |
| Keyinroq beriladi | qiymatsiz maydon | izoh; |
Ko'p jamoalar yana bir odatni qo'shadi: argumentdan keladigan xususiyatlar ham tepada qiymatsiz maydon sifatida e'lon qilinadi. Shunda klassning birinchi qatorlari — nusxaning to'liq "pasporti":
class Taom {
nom;
narx;
sotildi = 0;
constructor(nom, narx) {
this.nom = nom;
this.narx = narx;
}
}
console.log(new Taom("Manti", 30000));Konsolda:
Taom { nom: 'Manti', narx: 30000, sotildi: 0 }Klassni ochgan odam konstruktorni o'qimasdan ham "taomda nom, narx, sotildi bor" deb biladi. JavaScript dvigateli uchun ham bu foydali: hamma nusxa bir xil tartibda, bir xil xususiyatlar bilan yaratiladi.
Tekshirib ko'ring:
class Taom { narx; }dan keyin"narx" in new Taom()vanew Taom().narxnima qaytaradi?
Javob
true va undefined. Xususiyat bor, faqat qiymati undefined. Maydonsiz klassda esa "narx" in new Taom() — false bo'lardi: xususiyat umuman yaratilmagan. Farq kichik, lekin Object.keys, JSON.stringify va in tekshiruvlarida ko'rinadi.
4.1 Klassdan tashqarida xususiyat qo'shish
JavaScript nusxaga istalgan paytda yangi xususiyat qo'shishga ruxsat beradi:
class Taom {
nom;
constructor(nom) {
this.nom = nom;
}
}
const osh = new Taom("Osh");
osh.achchiqmi = false; // klassda yo'q edi
console.log(osh); // Taom { nom: 'Osh', achchiqmi: false }Ishlaydi, lekin bu odat yaxshi emas. Endi Taom nusxalari ikki xil: ba'zisida achchiqmi bor, ba'zisida yo'q. Klassni o'qigan odam bu xususiyat haqida bilmaydi — u kodning boshqa chekkasida, qandaydir funksiya ichida paydo bo'lgan. Xato qidirganda "bu maydon qayerdan keldi?" degan savol vaqt oladi.
Qoida: nusxada bo'lishi mumkin bo'lgan har bir xususiyat klassda maydon sifatida e'lon qilinsin. Qiymati hali noma'lum bo'lsa — qiymatsiz maydon (achchiqmi;) yoki null. Shunda klass — nusxaning to'liq va yagona tavsifi.
Bu odat dvigatelga ham yordam beradi: bir xil tuzilishdagi obyektlar bilan JavaScript tezroq ishlaydi, chunki ularning "shaklini" bir marta o'rganib, qayta-qayta ishlatadi. Bu mavzuga JS dvigateli ichida darsida qaytamiz.
4.2 Hisoblangan maydon nomi
Maydon nomi o'zgaruvchidan ham olinishi mumkin — obyekt literalidagi computed kalitlar kabi, kvadrat qavsda:
const kalit = "oshNarxi";
class Narxnoma {
[kalit] = 35000;
}
console.log(new Narxnoma()); // Narxnoma { oshNarxi: 35000 }Amalda bu kam uchraydi — asosan nomni Symbol bilan berishda (Symbol — keyinroq). Uni ko'rganingizda tanib olsangiz yetarli: kvadrat qavs ichidagi ifoda bir marta, klass e'lon qilinayotganda hisoblanadi.
5. Arrow maydon va this
5.1 Muammo: metodni tinglovchiga berish
this yo'qolishi darsidagi eng ko'p uchraydigan holat — metodni hodisa tinglovchisiga berish. Klass bilan:
<button type="button">Qo'shish</button>
<script>
class Hisoblagich {
soni = 0;
oshir() {
this.soni++;
console.log(this.soni);
}
}
const hisob = new Hisoblagich();
const tugma = document.querySelector("button");
tugma.addEventListener("click", hisob.oshir);
tugma.click();
</script>Konsolda:
NaN1 kutgan edik. Tinglovchi hisob.oshir ni obyektsiz oladi va brauzer uni chaqirganda this ga tugmani beradi (Hodisa obyekti). this.soni — tugmaning soni xususiyati, u yo'q: undefined + 1 — NaN. Hisoblagich esa 0 da qoldi. Natija oynasida "Qo'shish" ni bosib ko'ring — har bosishda NaN.
5.2 Yechim: arrow funksiya maydonda
Metodni oddiy metod emas, qiymati arrow funksiya bo'lgan maydon qilib yozamiz:
<button type="button">Qo'shish</button>
<script>
class Hisoblagich {
soni = 0;
oshir = () => {
this.soni++;
console.log(this.soni);
};
}
const hisob = new Hisoblagich();
const tugma = document.querySelector("button");
tugma.addEventListener("click", hisob.oshir);
tugma.click();
tugma.click();
</script>Konsolda:
1
2Nega ishladi? Arrow funksiyaning o'z this i yo'q — u yaratilgan joydagi this ni oladi (Arrow funksiyalar). Bu funksiya initializer ichida yaratildi, u yerda this — yangi nusxa. Demak oshir qayerdan, qanday chaqirilmasin, this doim hisob.
Tekshirib ko'ring: Arrow maydonli
Hisoblagichdaconst { oshir } = hisob; oshir();ishlaydimi?
Javob
Ishlaydi. Destructuring (Obyekt destructuring) funksiyani obyektdan "ajratib oladi" — oddiy metodda bu this ni yo'qotardi. Arrow funksiya esa this ni yaratilgan paytdayoq olib qo'ygan, uni qayerga olib borsangiz ham hisob bilan qoladi.
5.3 Narxi
Arrow maydon — qulay, lekin tekin emas. Oddiy metod bilan solishtiring:
class Hisoblagich {
soni = 0;
oshir() {
this.soni++;
}
kamaytir = () => {
this.soni--;
};
}
const a = new Hisoblagich();
const b = new Hisoblagich();
console.log(a.oshir === b.oshir); // true
console.log(a.kamaytir === b.kamaytir); // false
console.log(Object.keys(a)); // [ 'soni', 'kamaytir' ]Uchta farq:
- Xotira.
oshir— bitta, prototipda.kamaytir— har nusxada alohida funksiya. Ikkita hisoblagichda farq sezilmaydi; o'n ming obyektli ro'yxatda esa o'n ming funksiya. - U xususiyat, metod emas.
Object.keysvaconsole.loguni ko'rsatadi,JSON.stringifyesa tashlab yuboradi. Prototipda yo'qligi uchun uni meros klassda odatdagidek qayta yozish ham noqulay (Meros darsida ko'rasiz). - Initializer tartibiga bo'ysunadi. Undan oldingi maydon uni chaqira olmaydi — u hali yaratilmagan.
Amaliy qoida: arrow maydon — nusxasi kam, metodi tinglovchi yoki callback sifatida beriladigan klasslar uchun: sahifadagi bitta forma, bitta modal oyna, bitta o'yin. Ko'p nusxali "ma'lumot" klasslari — Taom, Vazifa — oddiy metod bilan qolsin; kerak bo'lsa, chaqiruv joyida o'rab bering: tugma.addEventListener("click", () => hisob.oshir()).
Tekshirib ko'ring:
tugma.addEventListener("click", hisob.oshir.bind(hisob))ham ishlaydimi? Arrow maydondan farqi nima?
Javob
Ishlaydi — bind this ni qotirilgan yangi funksiya qaytaradi (call, apply, bind). Farqi — qayerda bog'lanishi: bind faqat shu chaqiruv joyida, metod esa prototipda bitta bo'lib qoladi. Arrow maydon esa har nusxani yaratishda bog'laydi. Bitta joyda kerak bo'lsa — bind yoki arrow o'ram; ko'p joyda tinglovchi bo'lsa — arrow maydon qulayroq.
5.4 Uchta yo'lni solishtiramiz
Metod this siz chaqirilishi mumkin bo'lgan joyda uchta yechim bor. Ularni yonma-yon qo'yamiz:
| Yo'l | Qayerda yoziladi | Funksiyalar soni | Qachon |
|---|---|---|---|
Arrow o'ram () => h.oshir() |
chaqiruv joyida | har o'ramga bitta | bir-ikki joyda kerak |
h.oshir.bind(h) |
chaqiruv joyida | har bind ga bitta |
eski kodda ko'p |
Arrow maydon oshir = () => {} |
klassda | har nusxaga bitta | ko'p joyda tinglovchi |
Uchalasi ham to'g'ri. Farq — mas'uliyat kimda: o'ram va bind da metodni uzatayotgan kod this haqida o'ylaydi, arrow maydonda esa klassning o'zi. Jamoada bitta uslub tanlansa, kod bir xil o'qiladi.
Yana bitta nozik joy — tinglovchini keyin olib tashlash. removeEventListener aynan o'sha funksiyani so'raydi (addEventListener asoslari). tugma.addEventListener("click", () => hisob.oshir()) dan keyin xuddi shunday yangi o'ramni removeEventListener ga bersangiz — u boshqa funksiya, hech narsa o'chmaydi.
Arrow maydonda esa hisob.oshir har safar bitta funksiya — qo'shish ham, olib tashlash ham bir xil yoziladi. UI komponentlarda arrow maydon ko'p ishlatilishining ikkinchi sababi shu.
6. Brauzerlarda qo'llab-quvvatlanishi
Klass maydonlari tilga ES2022 da kirgan. Baseline ma'lumotiga ko'ra ochiq maydonlar 2022-yil sentyabridan barcha asosiy brauzerlarda bor (Safari 16 oxirgi bo'lib qo'shgan), 2025-yil martidan esa "keng qo'llab-quvvatlanadi" holatida. Node 12 dan beri ishlaydi. Ya'ni bugun ularni hech qanday qo'shimcha vositasiz bemalol ishlatasiz. Eski kodda maydonlar o'rniga hamma narsa constructor da yozilganini ko'rsangiz — bu shu sintaksisdan oldingi davrning izi.
Bunday eski klassni maydonlarga o'tkazish — xavfsiz refaktoring, lekin bitta narsani tekshiring: xususiyatlar tartibi o'zgaradi. «Sintaksis» bo'limidagi Buyurtma da stol birinchi o'rindan oxirgi o'ringa ko'chdi. Ilova xususiyatlar tartibiga tayanmasa (odatda tayanmaydi), farq faqat console.log va JSON.stringify natijasida ko'rinadi. Lekin JSON'ni satr sifatida solishtiradigan test yoki boshqa tizim bo'lsa — u "o'zgarish bor" deb aytadi. Shuning uchun refaktoringdan keyin JSON natijasini ham bir marta solishtirib ko'ring.
Tekshirib ko'ring:
class A { x = 1; constructor() { this.y = 2; } }—JSON.stringify(new A())nima qaytaradi?
Javob
{"x":1,"y":2}. Maydonlar — oddiy, sanaladigan o'z xususiyatlar, shuning uchun JSON ularni oladi. Tartib — yaratilish tartibi: avval maydon x, keyin constructor dagi y.
7. Ko'p uchraydigan xatolar
7.1 Obyekt literalidagi kabi ikki nuqta
class Taom {
nom: "Osh";
}SyntaxError: Unexpected identifier 'nom'Tarjimasi: "kutilmagan nom: nom". Xabar nom ni ko'rsatadi, lekin xato undan keyingi : da — klass tanasida kalit: qiymat yozuvi yo'q. Xabar ko'rsatgan so'z atrofini, ayniqsa undan keyingi belgini tekshiring. Tuzatish: nom = "Osh";.
7.2 Maydon oldida let yoki const
class Taom {
let narx = 35000;
}SyntaxError: Unexpected identifier 'narx'Tarjimasi: "kutilmagan nom: narx". Klass tanasi — o'zgaruvchilar e'lon qilinadigan joy emas, u yerda faqat maydonlar va metodlar turadi. JavaScript let ni maydon nomi deb o'qidi, keyin narx ni kutmadi. Tuzatish: narx = 35000;.
7.3 Metodda this. siz maydon
taomlar.push(taom) — ReferenceError: taomlar is not defined. Maydon — o'zgaruvchi emas, nusxaning xususiyati. Tuzatish: this.taomlar.push(taom).
7.4 Initializer'da constructor parametri
«Initializer constructor parametrlarini ko'rmaydi» bo'limidagi ReferenceError. Tuzatish: argumentga bog'liq hisobni constructor ga ko'chiring.
7.5 Maydonlar tartibi
Keyingi maydonga tayanadigan maydon — NaN yoki undefined, xato xabarisiz. Tuzatish: tayanilgan maydonni yuqoriga qo'ying.
8. Mashqlar
1-mashq (oson): Stol klassi
Stol klassini yozing: band = false va buyurtmalar = [] maydonlari, constructor(raqam). Ikkita stol yaratib, bittasining buyurtmalar iga "osh" qo'shing va ikkinchisi bo'sh qolganini ko'rsating.
Yechim
class Stol {
band = false;
buyurtmalar = [];
constructor(raqam) {
this.raqam = raqam;
}
}
const birinchi = new Stol(1);
const ikkinchi = new Stol(2);
birinchi.buyurtmalar.push("osh");
console.log(birinchi.buyurtmalar); // [ 'osh' ]
console.log(ikkinchi.buyurtmalar); // []Har new da [] qaytadan hisoblandi — har stolning o'z massivi.
2-mashq (o'rta): Tartibni oldindan ayting
Kodni ishga tushirmasdan, konsolda nima chiqishini yozing. Keyin Node'da tekshiring.
class Narx {
asosiy = 28000;
xizmat = this.asosiy * 0.1;
jami = this.asosiy + this.xizmat;
constructor(chegirma) {
this.jami = this.jami - chegirma;
}
}
console.log(new Narx(800));Yechim
class Narx {
asosiy = 28000;
xizmat = this.asosiy * 0.1;
jami = this.asosiy + this.xizmat;
constructor(chegirma) {
this.jami = this.jami - chegirma;
}
}
console.log(new Narx(800));Konsolda:
Narx { asosiy: 28000, xizmat: 2800, jami: 30000 }Maydonlar yuqoridan pastga: asosiy → xizmat (28000 × 0.1) → jami (30 800). So'ng constructor jami dan 800 ni ayirdi — 30 000.
3-mashq (qiyin): Arrow maydon qachon kerak?
«Bahor» sahifasida bitta Taymer bor: u har soniyada ekrandagi vaqtni yangilaydi. Uning yangila metodi setInterval ga beriladi. Funksiya setInterval(fn, 1000) berilgan fn ni har 1000 millisekundda chaqiradi. Uni 11-qismda, Taymerlar darsida batafsil o'rganamiz. Hozir faqat shuni biling: u ham metodni obyektsiz chaqiradi. yangila ni oddiy metod yoki arrow maydon qilib yozasizmi? Javobni asoslang va Node'da setInterval o'rniga oddiy chaqiruv bilan tekshiring.
Yechim
Arrow maydon mos keladi: Taymer sahifada bitta, metod esa obyektsiz chaqiriladi. Xotira narxi — bitta funksiya, sezilmaydi.
class Taymer {
soniya = 0;
yangila = () => {
this.soniya++;
return this.soniya;
};
}
const taymer = new Taymer();
const chaqiruvchi = taymer.yangila; // setInterval ham shunday oladi
console.log(chaqiruvchi()); // 1
console.log(chaqiruvchi()); // 2Oddiy metod bo'lsa, chaqiruvchi() da this — undefined va TypeError: Cannot read properties of undefined (reading 'soniya'). Agar Taymer ming nusxali bo'lganida (masalan, har buyurtmaning o'z taymeri) — oddiy metod va chaqiruv joyida () => taymer.yangila() yaxshiroq bo'lardi.
4-mashq: Vazifalar qadami — Vazifa ning pasporti
refactor/vazifa-klassi branch'ida davom etamiz. O'tgan darsda Vazifa shunday bo'ldi:
class Vazifa {
constructor(id, matn, bajarildi = false) {
this.id = id;
this.matn = matn;
this.bajarildi = bajarildi;
}
almashtir() {
this.bajarildi = !this.bajarildi;
}
}«Nima maydonga, nima constructor ga?» bo'limidagi jadvalga qarab qaror qiling:
- Klass tepasiga nusxaning "pasporti"ni — maydonlar ro'yxatini — qo'shing.
- Qaysi maydonga initializer kerak, qaysisiga yo'q?
bajarildi = falseni maydonga ko'chirish kerakmi? almashtirni arrow maydonga aylantirish kerakmi?
Xulq o'zgarmasin.
Yechim
class Vazifa {
id;
matn;
bajarildi;
constructor(id, matn, bajarildi = false) {
this.id = id;
this.matn = matn;
this.bajarildi = bajarildi;
}
almashtir() {
this.bajarildi = !this.bajarildi;
}
}Qarorlar:
- Uchala maydon — initializer'siz. Uchalasining qiymati tashqaridan keladi:
idvamatn— har doim,bajarildi— ixtiyoriy (boshlang'ich ma'lumotdatruebo'lishi mumkin). Jadvaldagi "tashqaridan, argument bilan" qatori —constructor. Maydonlar ro'yxati faqat "pasport" vazifasini bajaradi. bajarildi = false— default parametrda qoladi. Uni maydonga ko'chirsangiz (bajarildi = false;),constructorbaribirthis.bajarildi = bajarildibilan uning ustiga yozadi — ikki joyda ikki xil "sukut" paydo bo'ladi. Sukut bir joyda tursin.almashtir— oddiy metod.vazifalarda u tinglovchiga berilmaydi: delegation tinglovchisivazifaniAlmashtir(id)ni chaqiradi, u esavazifaniTop(id).almashtir()— obyekt orqali. Vazifalar esa ko'p bo'lishi mumkin. Arrow maydon bu yerda faqat xotira sarflardi.
Tekshiring: console.log(holat.vazifalar[0]) — Vazifa { id: 1, matn: 'Non olish', bajarildi: false }, tartib avvalgidek. Sahifada o'tgan darsdagi ro'yxat bo'yicha sinang: belgilash, qo'shish, tahrirlash, Esc, o'chirish, filtrlar, bo'sh holat — hammasi o'zgarmagan.
Commit: Vazifalar: Vazifa klassiga maydonlar ro'yxatini qo'sh.
9. Real ishda
- UI komponentlar. Web Components (
class MenyuKartasi extends HTMLElement) va eski React klass komponentlaridahandleClick = () => {...}— arrow maydon — eng ko'p uchraydigan qolip. Sababi bugungi darsdagi: metod tinglovchiga beriladi. - Uslub qo'llanmalari. Ko'p jamoalarning kod qoidalari klass a'zolari tartibini belgilaydi: avval maydonlar, keyin
constructor, keyin metodlar. Bugungi darsdagi barcha misollar shu tartibda yozildi — u o'qish uchun ham, initializer tartibini eslab qolish uchun ham qulay. - TypeScript (15-qism) maydonlarga tur yozadi:
taomlar: string[] = []. Sintaksis bugungisining ustiga quriladi. - Kod ko'rib chiqish. "Nega bu ma'lumot klassida arrow maydon?" — tajribali ko'rib chiquvchi beradigan savol. Endi siz xotira narxini va muqobilini bilasiz.
- Intervyu. "Klass maydonlari va
constructorqaysi tartibda ishlaydi?", "Arrow maydon va metod farqi?" — middle darajadagi savollar.
Xulosa
- Klass maydoni —
nom = qiymat;klass tanasida; u har nusxaning o'z xususiyati bo'ladi, prototipda emas. - Initializer har
newda qaytadan hisoblanadi:taomlar = []har nusxaga alohida massiv beradi. - Tartib: bo'sh obyekt → maydonlar yuqoridan pastga →
constructortanasi; initializerconstructorparametrlarini ko'rmaydi. - Bir xil boshlanadigan qiymat — maydonga, tashqaridan keladigani —
constructorga; qiymatsiz maydon "pasport" sifatida foydali. - Arrow maydon
thisni nusxaga qotiradi, lekin har nusxaga alohida funksiya yaratadi — kam nusxali, tinglovchi klasslar uchun.
Keyingi dars: Private # maydon va metodlar — klass tashqarisidan umuman ko'rinmaydigan maydonlarni yozamiz va Vazifa matnini tasodifiy o'zgarishdan himoyalaymiz.
Manbalar
- MDN: "Public class fields", "Classes" — developer.mozilla.org
- ECMAScript 2025 Language Specification: "ClassFieldDefinition", "InitializeInstanceElements" — tc39.es/ecma262
- web-features:
javascript.classes.public_class_fields— Baseline 2022-09, keng qo'llab-quvvatlanadi 2025-03 dan
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!