25 август 2025

Reference Type (Havola turi)

Chuqur til xususiyati

Bu maqola murakkab mavzuni qamrab oladi, ma’lum edge-caselarni yaxshiroq tushunish uchun.

Bu muhim emas. Ko’plab tajribali dasturchilar buni bilmasdan ham yaxshi yashaydi. Agar narsalar parda ortida qanday ishlashini bilishni istasangiz, o’qishda davom eting.

Dinamik baholanadigan metod chaqiruvi this ni yo’qotishi mumkin.

Masalan:

let user = {
  name: "John",
  hi() { alert(this.name); },
  bye() { alert("Xayr"); }
};

user.hi(); // ishlaydi

// endi nomga qarab user.hi yoki user.bye ni chaqiramiz
(user.name == "John" ? user.hi : user.bye)(); // Xato!

Oxirgi qatorda user.hi yoki user.bye ni tanlaydigan shartli operator bor. Bu holda natija user.hi dir.

Keyin metod darhol qavs () bilan chaqiriladi. Lekin u to’g’ri ishlamaydi!

Ko’rib turganingizdek, chaqiruv xatoga olib keladi, chunki chaqiruv ichida "this" ning qiymati undefined bo’ladi.

Bu ishlaydi (objekt nuqta metod):

user.hi();

Bu ishlamaydi (baholangan metod):

(user.name == "John" ? user.hi : user.bye)(); // Xato!

Nima uchun? Agar biz nima uchun shunday bo’lishini tushunmoqchi bo’lsak, obj.method() chaqiruvi qanday ishlashining parda ortiga qaraylik.

Reference type tushuntirilishi

Diqqat bilan qarasak, obj.method() ifodasida ikkita amal borligini ko’ramiz:

  1. Birinchidan, nuqta '.' obj.method xususiyatini oladi.
  2. Keyin qavs () uni bajaradi.

Xo’sh, this haqidagi ma’lumot birinchi qismdan ikkinchisiga qanday o’tkaziladi?

Agar bu amallarni alohida qatorlarga qo’ysak, this albatta yo’qoladi:

let user = {
  name: "John",
  hi() { alert(this.name); }
}

// metodni olish va chaqirishni ikki qatorga ajratish
let hi = user.hi;
hi(); // Xato, chunki this undefined

Bu yerda hi = user.hi funktsiyani o’zgaruvchiga joylashtiradi va keyin oxirgi qatorda u butunlay mustaqil bo’ladi va shuning uchun this yo’q.

user.hi() chaqiruvlari ishlashi uchun JavaScript hiyla ishlatadi – nuqta '.' funktsiya emas, balki maxsus Reference Type qiymatini qaytaradi.

Reference Type "spetsifikatsiya turi"dir. Biz uni aniq ishlatib bo’lmaydi, lekin u til tomonidan ichki ishlatiladi.

Reference Type qiymati uch qiymatli kombinatsiya (base, name, strict) dir, bu yerda:

  • base – objekt.
  • name – xususiyat nomi.
  • strict – agar use strict kuchda bo’lsa true.

user.hi xususiyatiga kirish natijasi funktsiya emas, balki Reference Type qiymati. Qat’iy rejimda user.hi uchun bu:

// Reference Type qiymati
(user, "hi", true)

Reference Type da qavs () chaqirilganda, ular objekt va uning metodi haqidagi to’liq ma’lumotni oladi va to’g’ri this ni o’rnatishi mumkin (bu holda =user).

Reference type nuqta . dan chaqiruv qavslari () ga ma’lumot uzatish maqsadida maxsus “vositachi” ichki tur.

hi = user.hi kabi har qanday boshqa amal reference type ni butunlay bekor qiladi, user.hi qiymatini (funktsiya) oladi va uni uzatadi. Shuning uchun har qanday keyingi amal this ni “yo’qotadi”.

Shunday qilib, natijada this qiymati faqat funktsiya to’g’ridan-to’g’ri nuqta obj.method() yoki kvadrat qavs obj['method']() sintaksisi yordamida chaqirilgandagina to’g’ri yo’l bilan uzatiladi (ular bu yerda bir xil). Bu muammoni hal qilishning turli usullari bor, masalan func.bind().

Xulosa

Reference Type – tilning ichki turi.

Xususiyatni o’qish, masalan obj.method() dagi nuqta . bilan, aynan xususiyat qiymatini emas, balki xususiyat qiymati va u olingan objektni saqlaydigan maxsus “reference type” qiymatini qaytaradi.

Bu keyingi metod chaqiruvi () objektni olishi va unga this ni o’rnatishi uchun.

Barcha boshqa amallar uchun reference type avtomatik ravishda xususiyat qiymatiga aylanadi (bizning holatda funktsiya).

Butun mexanizm bizning ko’zlarimizdan yashirin. Bu faqat nozik hollarda muhim, masalan metod objekt ifoda yordamida dinamik ravishda olinganda.

Vazifalar

Ushbu kod natijasi qanday?

let user = {
  name: "John",
  go: function () {
    alert(this.name);
  },
}(user.go)();

P.S. Xatolik bor :)

Xato!

Urunib ko’ring:

let user = {
  name: "John",
  go: function () {
    alert(this.name);
  },
}(user.go)(); // xato!

Ko’pgina brauzerlardagi xato xabari nima bo’lganligini tushunishga imkon bermaydi.

Xato user = {...} dan keyin paydo bo’ladi, chunki nuqta-vergul yo’q.

Javascript (user.go)() qavsidan oldin vergulni qabul qilmaydi, shuning uchun u quyidagi kodni o’qiydi:

let user = { go:... }(user.go)()

Bundan tashqari, biz bunday qo’shma ifoda sintaktik ravishda {go: ...} ob’ektini (user.go) argumenti bilan funktsiya sifatida chaqirishini ko’rishimiz mumkin. Va bu xuddi shu satrda let user bilan sodir bo’ladi, shuning uchun user ob’ekti hali aniqlanmagan, shuning uchun xato.

Agar biz nuqta-vergul qo’shsak, barchasi yaxshi:

let user = {
  name: "John",
  go: function() { alert(this.name) }
};

(user.go)() // John

Iltimos e’tibor bering, (user.go) atrofidagi qavslar bu erda hech narsa qilmaydi. Odatda ular operatsiyalar tartibini o’rnatadilar, ammo bu erda nuqta . baribir avval ishlaydi, shuning uchun hech qanday ta’sir bo’lmaydi. Faqat nuqta-vergul muhim.

Quyidagi kodda biz ketma-ket 4 marta user.go() usulini chaqirmoqchimiz.

Ammo (1) va (2) chaqiruvlari (3) va (4) dan farq qiladi. Nima uchun?

let obj, method;

obj = {
  go: function () {
    alert(this);
  },
};

obj.go(); // (1) [object Object]

obj.go(); // (2) [object Object]

(method = obj.go)(); // (3) undefined

(obj.go || obj.stop)(); // (4) undefined

Quyida tushuntirishlar.

  1. Bu odatiy obyekt usulini chaqiruvi.

  2. Xuddi shu, qavslar bu yerda ishlash tartibini o’zgartirmaydi, nuqta baribir birinchi o’rinda turadi.

  3. Bu erda biz (ifoda).method() yanada murakkab chaqiruvga egamiz. Chaqiruv xuddi ikkita satrga bo’linganidek ishlaydi:

    f = obj.go; // ifodani hisoblang
    f();        // paydo bo'lgan narsani chaqiring

    Bu yerda f() funktsiya sifatida this siz bajariladi.

  4. Shunga o’xshash narsa (3), nuqta chap tomonida . bizda iboralar mavjud.

(3) va (4) xatti-harakatlarini tushuntirish uchun xususiyatga kiruvchilar (nuqta yoki kvadrat qavslar) havola turining qiymatini qaytarishini esga olishimiz kerak.

Unda usul chaqiruvidan tashqari har qanday operatsiya (masalan, = yoki || topshirig’i kabi) uni oddiy qiymatga aylantiradi, bu this o’rnatishga imkon beradigan ma’lumotni o’z ichiga olmaydi.

O'quv qo'llanma xaritasi

Izohlar

izoh berishdan oldin buni o'qing…
  • Agar sizda nimani yaxshilash kerakligi haqida takliflaringiz bo'lsa - iltimos, GitHub muammosini yuboring yoki izoh berish o'rniga so'rov yuboring.
  • Agar siz maqolada biror narsani tushunolmasangiz - iltimos, batafsilroq ma'lumot bering.
  • Bir nechta so'z so'zlarini kiritish uchun <code> yorlig'ini ishlating, bir nechta satrlar uchun - ularni <pre> yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepen…)