this parametri — kontekst turi, noImplicitThis
Hisoblagich ob'ekti yozilgan. oshirish metodi tugmaga bog'lanadi:
const hisoblagich = {
qiymat: 0,
oshirish() {
this.qiymat++; // bu yerda this = hisoblagich
}
};
btn.addEventListener("click", hisoblagich.oshirish);
// Tugma bosilganda: this = btn (HTMLButtonElement)
// this.qiymat++ — undefined++, natija NaN
this kontekstga qarab o'zgaradi. JavaScript da bu keng tarqalgan muammo. TypeScript noImplicitThis: true bilan this turini aniq belgilashni talab qiladi.
this parametri
TypeScript funksiyada this turini birinchi parametr sifatida belgilashga imkon beradi. Bu haqiqiy parametr emas — faqat tur tekshirish uchun:
interface Hisoblagich {
qiymat: number;
oshirish(this: Hisoblagich): void;
}
const hisoblagich: Hisoblagich = {
qiymat: 0,
oshirish() {
this.qiymat++; // ✅ — this: Hisoblagich, .qiymat mavjud
}
};
Noto'g'ri kontekstda chaqirish
this parametri yozilganda TypeScript noto'g'ri kontekstda chaqirishni to'xtatadi:
interface Hisoblagich {
qiymat: number;
oshirish(this: Hisoblagich): void;
}
function chaqir(fn: () => void) { fn(); }
chaqir(hisoblagich.oshirish);
// ❌ — The 'this' context of type 'void' is not assignable to type 'Hisoblagich'
To'g'ri yechim — bind yoki arrow funksiya:
btn.addEventListener("click", () => hisoblagich.oshirish());
// ✅ — arrow funksiya o'z this ini saqlaydi
btn.addEventListener("click", hisoblagich.oshirish.bind(hisoblagich));
// ✅ — bind bilan kontekst belgilanadi
noImplicitThis
tsconfig.json da "noImplicitThis": true (strict: true bilan avtomatik yoqiladi) bo'lganda — this turi aniqlanmagan funksiyada xato:
function yukla(this, url: string) { // ❌ — this turi noma'lum
console.log(this.baseUrl + url);
}
this turi belgilanishi kerak:
interface Yuklash {
baseUrl: string;
}
function yukla(this: Yuklash, url: string): void {
console.log(this.baseUrl + url); // ✅
}
Arrow funksiya va this
Arrow funksiya o'z this ni yaratmaydi — uni o'rab turgan kontekstdan oladi:
class Taymer {
hisoblagich = 0;
boshlash() {
setInterval(() => {
this.hisoblagich++; // ✅ — arrow funksiya, this = Taymer instansiyasi
console.log(this.hisoblagich);
}, 1000);
}
}
Oddiy funksiya bilan:
class Taymer {
hisoblagich = 0;
boshlash() {
setInterval(function() {
this.hisoblagich++; // ❌ — this = undefined (strict mode da)
}, 1000);
}
}
Class metodlari ichida callback — arrow funksiya ishlating.
Tez-tez uchraydigan xatolar
Metodni o'zgaruvchiga olib, chaqirish:
const obj = {
qiymat: 42,
olish(this: typeof obj) { return this.qiymat; }
};
const fn = obj.olish;
fn(); // ❌ — this konteksti yo'q
obj.olish(); // ✅
Class metodini callback sifatida berish:
class Xizmat {
ism = "API";
logla() { console.log(this.ism); }
}
const x = new Xizmat();
setTimeout(x.logla, 1000); // ❌ — this yo'qoladi
setTimeout(() => x.logla(), 1000); // ✅
Xulosa
// this parametri — haqiqiy parametr emas, faqat tur uchun
function fn(this: Tur, a: string): void { ... }
// Arrow funksiya — this ni o'rab turgan kontekstdan oladi
const fn = () => this.qiymat; // ✅ — this tashqaridan
// bind — kontekstni qat'iy belgilash
const bog_langan = metod.bind(ob_ekt);
Oddiy funksiya → this chaqiruvchi ob'ektga qarab o'zgaradi
Arrow funksiya → this yaratilgan joydan olinadi (leksik)
.bind(obj) → this obj ga qat'iy bog'lanadi
Keyingi dars
27-dars: typeof va instanceof — type narrowing