Ob'ekt metodlari — this kalit so'zi

~20 daq · JavaScript · Ob'ektlar va Massivlar

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 → window yoki strict modeda undefined
  • Arrow function da → yuqoridagi this (meros)
  • new bilan → 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