Klasslar

Klass asosiy sintaksisi

Amaliyotda biz ko'pincha bir turdagi ko'plab obyektlarni yaratishga muhtoj bo'lamiz โ€” masalan, foydalanuvchilar, tovarlar yoki hujjatlar. Buni new function orqali ham qilish mumkin, ammo zamonaviy JavaScript'da buning uchun ancha qulay va kuchli class (klass) sintaksisi mavjud.

"class" sintaksisi

Asosiy sintaksis quyidagicha ko'rinadi:

class MyClass {
  // metodlar
  constructor() { ... }
  method1() { ... }
  method2() { ... }
  method3() { ... }
}

So'ng new MyClass() orqali sanab o'tilgan barcha metodlarga ega yangi obyekt yaratamiz. Bunda constructor() metodi avtomatik chaqiriladi โ€” shu sababli obyektni tayyorlash (ya'ni boshlang'ich holatini o'rnatish) mantiqini aynan shu yerga yozamiz.

Keling, oddiy bir User klassini yozamiz:

klass-user.js
// natija shu yerda chiqadi

Bu yerda nima sodir bo'lyapti:

  1. new User("Ali") chaqirilganda yangi obyekt yaratiladi;
  2. constructor ishga tushadi, unga "Ali" argument sifatida uzatiladi va u this.nameni o'rnatadi;
  3. Endi biz obyekt metodlarini, masalan user.sayHi()ni, chaqira olamiz.
Klass metodlari orasiga vergul qo'yilmaydi. Bu ko'p yangi boshlovchilar yo'l qo'yadigan xato. Klass ichidagi yozuv obyekt literalidan farq qiladi: bu yerda vergul emas, metodlar ketma-ket yoziladi.

class โ€” bu funksiya

Aslida JavaScript'da class โ€” bu alohida, mutlaqo yangi tushuncha emas. U aslida funksiya turining bir ko'rinishi. Keling, tekshirib ko'ramiz:

klass-typeof.js
// natija shu yerda chiqadi

class User { ... } konstruksiyasi aslida quyidagilarni bajaradi:

  1. User nomli funksiya yaratadi. Funksiya kodi constructor metodidan olinadi (agar constructor yozilmagan bo'lsa, bo'sh deb hisoblanadi);
  2. Klass ichidagi metodlarni (masalan sayHi) User.prototypega saqlaydi.

Ya'ni new User chaqirilganda va obyekt metodi ishlatilganda, metod prototipdan olinadi โ€” huddi biz o'zimiz User.prototype.sayHi = ... deb yozganimizdek.

klass-prototype.js
// natija shu yerda chiqadi

Class shunchaki "shirin sintaksis" emas

Ba'zan class โ€” bu "syntactic sugar" (sintaksik shakar), ya'ni faqat yozuvni chiroyli qiladigan bezak deyishadi. Lekin bu to'liq to'g'ri emas, chunki class'ning muhim farqlari bor:

Klassni newsiz oddiy funksiya kabi chaqirish mumkin emas. Masalan, User() (yangilamasdan) โ€” "Class constructor User cannot be invoked without 'new'" xatosini beradi.

Class ifodasi (Class Expression)

Funksiyalar kabi, klasslarni ham boshqa ifoda ichida aniqlash, o'zgaruvchiga berish yoki qaytarish mumkin. Bu class ifodasi deyiladi:

klass-expression.js
// natija shu yerda chiqadi

Named Function Expression (NFE) kabi, class ifodasining ham nomi bo'lishi mumkin. Bu nom faqat klass ichida ko'rinadi:

klass-nfe.js
// natija shu yerda chiqadi

Klasslarni "talab bo'yicha" (dinamik) yaratish ham mumkin โ€” masalan, funksiyadan qaytarish orqali:

klass-factory.js
// natija shu yerda chiqadi

Getter va setter'lar

Oddiy obyektlar kabi, klasslar ham get/set orqali hisoblanadigan xossalarni qo'llab-quvvatlaydi. Ular obj.propni o'qish yoki yozishda avtomatik chaqiriladi:

klass-getset.js
// natija shu yerda chiqadi

Texnik jihatdan bunday getter/setter User.prototypeda yaratiladi. _name โ€” bu ichki qiymatni saqlash uchun "maxfiy" xossa (bu haqda keyingi darslarda batafsil to'xtalamiz).

Hisoblangan nomlar [...]

Metod nomini kvadrat qavslar [...] ichida hisoblab olish mumkin. Bu obyekt literalidagi hisoblangan xossalarga o'xshaydi:

klass-computed.js
// natija shu yerda chiqadi

Class maydonlari (Class fields)

Zamonaviy JavaScript'da klassga to'g'ridan-to'g'ri xossa (maydon) qo'shish mumkin. Buning uchun constructor shart emas:

klass-fields.js
// natija shu yerda chiqadi

Muhim farq: klass maydonlari prototypeda emas, balki har bir obyektning o'zida o'rnatiladi. Ya'ni name โ€” user obyektiga tegishli, User.prototypega emas.

Klass maydonlari thisni bog'lash muammosini hal qilish uchun ham juda foydali โ€” maydon sifatida yozilgan strelka funksiya har doim o'z obyektiga bog'lanib qoladi. Bu haqda funksiyalar bo'limida batafsil to'xtalamiz.

Xulosa