Ob'ekt metodlari — this kalit so'zi
Muammodan boshlaylik
Siz ob'ekt yozdingiz. Ichida metod bor. Metod o'sha ob'ektning boshqa xususiyatiga murojaat qilishi kerak. Qanday?
const foydalanuvchi = {
ism: "Jasur",
salomlash: function () {
console.log("Salom, " + ???); // bu yerda ismni qanday olish kerak?
}
};
ism ni to'g'ridan-to'g'ri yozish mumkin emas — bu kod faqat shu ob'ekt uchun ishlaydi, boshqa ob'ektlarda ishlamaydi. Buning uchun this kerak.
this nima?
this — "men hozir kimning ichidaman?" degan savol. U funksiya ichida o'sha funksiyani chaqirgan ob'ektni ko'rsatadi.
Oddiy hayotiy o'xshatma: restoranda ofitsiant "mening stolimdagi mijoz" deydi. "Mening" so'zi — this. Qaysi ofitsiant gapirayotganiga qarab, "mening stolim" har safar boshqa stol bo'ladi. this ham xuddi shunday — kimning metodida ishlayotganiga qarab o'zgaradi.
const foydalanuvchi = {
ism: "Jasur",
salomlash: function () {
console.log("Salom, " + this.ism); // this = foydalanuvchi ob'ekti
},
};
foydalanuvchi.salomlash(); // "Salom, Jasur"
this.ism — "men qaysi ob'ektning metodiman, o'sha ob'ektning ism xususiyati".
this qiymati qayerda aniqlanadi?
Bu eng muhim tushuncha. this funksiya yozilgan joyda emas, funksiya chaqirilgan joyda aniqlanadi.
function kimMan() {
console.log(this.ism);
}
const ali = { ism: "Ali", ayt: kimMan };
const vali = { ism: "Vali", ayt: kimMan };
ali.ayt(); // "Ali" — this = ali
vali.ayt(); // "Vali" — this = vali
Bir xil funksiya, ikki xil natija. Chunki chaqiruvchi ob'ekt har xil.
this — to'rt xil holat
this ning qiymati to'rt xil holatda to'rt xil bo'ladi.
1. Metod ichida — chaqiruvchi ob'ekt
const mashina = {
model: "Nexia",
info: function () {
console.log(this.model); // this = mashina
},
};
mashina.info(); // "Nexia"
2. Oddiy funksiyada — global ob'ekt (yoki undefined)
Funksiya hech qanday ob'ektga tegishli bo'lmasa — this brauzerde window, Node.js da global ob'ektini ko'rsatadi. "use strict" rejimida esa undefined.
function tekshir() {
console.log(this); // brauzerde window, strict modeda undefined
}
tekshir();
"use strict";
function tekshir() {
console.log(this); // undefined
}
tekshir();
Bu ko'pincha kutilmagan xatolarga olib keladi:
const foydalanuvchi = {
ism: "Jasur",
salomlash: function () {
function ichkiFunksiya() {
console.log(this.ism); // undefined! this = window, chunki bu oddiy funksiya
}
ichkiFunksiya();
},
};
foydalanuvchi.salomlash();
3. Arrow function — o'zi yuqoridagi this ni oladi
Arrow function ning this i yo'q. U o'zi yozilgan joyning this ini meros oladi.
const foydalanuvchi = {
ism: "Jasur",
salomlash: function () {
const ichkiFunksiya = () => {
console.log(this.ism); // "Jasur" — this = foydalanuvchi (yuqoridan olindi)
};
ichkiFunksiya();
},
};
foydalanuvchi.salomlash(); // "Jasur"
Oldingi misolda ichkiFunksiya oddiy funksiya edi — this yo'qoldi. Arrow function ga o'zgartirilganda this saqlanib qoldi.
4. Constructor da — yangi yaratilgan ob'ekt
new kalit so'zi bilan chaqirilganda this yangi yaratilayotgan ob'ektni ko'rsatadi. Bu keyingi darslarda batafsil ko'riladi.
function Foydalanuvchi(ism) {
this.ism = ism; // this = yangi ob'ekt
}
const jasur = new Foydalanuvchi("Jasur");
console.log(jasur.ism); // "Jasur"
this ni qo'lda belgilash — call, apply, bind
Ba'zan funksiyaning this ni o'zingiz belgilashingiz kerak. Buning uchun uchta metod bor.
call — chaqirish va this belgilash
function salomlash(shahar, yosh) {
console.log(`Salom, men ${this.ism}, ${shahar}dan, ${yosh} yoshda`);
}
const ali = { ism: "Ali" };
const vali = { ism: "Vali" };
salomlash.call(ali, "Toshkent", 25); // "Salom, men Ali, Toshkentdan, 25 yoshda"
salomlash.call(vali, "Samarqand", 22); // "Salom, men Vali, Samarqanddan, 22 yoshda"
call(ob'ekt, arg1, arg2, ...) — birinchi argument this, qolganlari oddiy argumentlar.
apply — call bilan bir xil, argumentlar massivda
salomlash.apply(ali, ["Toshkent", 25]);
// "Salom, men Ali, Toshkentdan, 25 yoshda"
apply va call ning farqi faqat argumentlar berilish usulida. call — alohida-alohida, apply — massivda.
bind — yangi funksiya qaytaradi
call va apply funksiyani darhol chaqiradi. bind esa this bog'langan yangi funksiya qaytaradi — keyinroq chaqirish uchun.
function salomlash() {
console.log(`Salom, ${this.ism}`);
}
const ali = { ism: "Ali" };
const aliSalomlash = salomlash.bind(ali); // ← yangi funksiya, this = ali qotib qoldi
aliSalomlash(); // "Salom, Ali"
aliSalomlash(); // "Salom, Ali" — har safar ali bilan
bind ayniqsa event handler larda foydali:
const hisoblagich = {
son: 0,
oshir: function () {
this.son++;
console.log(this.son);
},
};
setTimeout(hisoblagich.oshir, 1000); // NaN — this yo'qoldi
setTimeout(hisoblagich.oshir.bind(hisoblagich), 1000); // 1 — bind bilan saqlanadi ✅
Arrow function va this — muhim farq
Arrow function metod sifatida ishlatilganda this kutilganday ishlamaydi. Chunki u o'zining this ini yaratmaydi — yuqoridan oladi.
const foydalanuvchi = {
ism: "Jasur",
salomlashOddiy: function () {
console.log(this.ism); // "Jasur" ✅
},
salomlashArrow: () => {
console.log(this.ism); // undefined ❌ — this = window (ob'ekt tashqarisidan olindi)
},
};
Qoida: Ob'ekt metodlari uchun har doim oddiy funksiya yoki qisqa metod sintaksisi. Arrow function faqat ichki funksiyalar uchun — this ni saqlab qolish kerak bo'lganda.
const foydalanuvchi = {
ism: "Jasur",
do_stlar: ["Ali", "Vali", "Soli"],
barchagaSalomlash: function () {
this.do_stlar.forEach((do_st) => { // ← arrow function — this saqlanadi
console.log(`${this.ism} → ${do_st} ga salom`);
});
}
};
foydalanuvchi.barchagaSalomlash();
// "Jasur → Ali ga salom"
// "Jasur → Vali ga salom"
// "Jasur → Soli ga salom"
Qisqa metod sintaksisi
ES6 dan boshlab ob'ekt metodlarini qisqaroq yozish mumkin:
// Eski usul
const ob = {
salomlash: function () {
console.log(this.ism);
}
};
// Yangi qisqa usul — ko'proq ishlatiladi
const ob = {
salomlash() {
console.log(this.ism);
}
};
Ikkalasi bir xil ishlaydi — this xuddi shunday bog'lanadi.
Tez-tez uchraydigan xatolar
Metodga havola olish — this yo'qoladi:
const hisoblagich = {
son: 10,
korsat: function () {
console.log(this.son);
},
};
hisoblagich.korsat(); // 10 ✅
const fn = hisoblagich.korsat; // faqat funksiyani oldik — ob'ektdan "ajraldi"
fn(); // undefined ❌ — this = window
Sababi: funksiyaga havola olganda u ob'ektdan uziladi, this bilan aloqasi yo'qoladi.
const fn = hisoblagich.korsat.bind(hisoblagich); // ← bind bilan tuzatiladi
fn(); // 10 ✅
Ichki funksiyada this yo'qolishi:
const ob = {
qiymat: 42,
hisobla: function () {
function ichki() {
console.log(this.qiymat); // undefined ❌ — ichki oddiy funksiyada this yo'q
}
ichki();
const ichkiArrow = () => {
console.log(this.qiymat); // 42 ✅ — arrow this ni yuqoridan oladi
};
ichkiArrow();
}
};
Arrow function ni metod sifatida ishlatish:
// ❌ Xato
const ob = {
ism: "Jasur",
salomlash: () => {
console.log(this.ism); // undefined
}
};
// ✅ To'g'ri
const ob = {
ism: "Jasur",
salomlash() {
console.log(this.ism); // "Jasur"
}
};
Xulosa
this — funksiya ichida o'sha funksiyani chaqirgan ob'ektni ko'rsatadi. U funksiya yozilgan joyda emas, chaqirilgan joyda aniqlanadi.
To'rt holat:
- Metod ichida → chaqiruvchi ob'ekt
- Oddiy funksiyada →
windowyoki strict modedaundefined - Arrow function da → yuqoridagi
this(meros) newbilan → yangi yaratilgan ob'ekt
call, apply, bind — this ni qo'lda belgilash uchun. call/apply darhol chaqiradi, bind yangi funksiya qaytaradi.
Arrow function — ob'ekt metodlari uchun emas, ichki funksiyalar uchun.
Keyingi dars
19-dars: Ob'ekt metodlari — Object.keys, values, entries, assign, freeze