Ob'ekt usullari, "this"

Ob'ektlar odatda real dunyo ob'ektlarini, masalan, foydalanuvchilar, buyurtmalar va boshqalarni ifodalash uchun yaratiladi.

Ob'ekt usullari, "this"

Ob'ektlar odatda real dunyo ob'ektlarini, masalan, foydalanuvchilar, buyurtmalar va boshqalarni ifodalash uchun yaratiladi:

let user = {
  name: 'John',
  age: 30,
};

Real hayotda foydalanuvchi biror narsani tanlashi, savatga qo'shishi, tizimga kirishi, chiqishi va hokazo harakatlarni amalga oshirishi mumkin.

JavaScript-da harakatlar xususiyatlardagi funksiyalar orqali ifodalanadi.

Usul misollari

Boshlanishiga, foydalanuvchini salomlashishga o'rgataylik:

let user = {
  name: 'John',
  age: 30,
};
 
user.sayHi = function () {
  alert('Hello!');
};
 
user.sayHi(); // Hello!

Bu yerda biz faqat Funksiya Ifodasini (Function Expression) ishlatib, funksiya yaratdik va uni ob'ektning user.sayHi xususiyatiga tayinladik.

Keyin uni user.sayHi() sifatida chaqirishimiz mumkin. Endi foydalanuvchi gapira oladi!

Ob'ektning xususiyati bo'lgan funksiya "usul" (method) deb ataladi.

Shunday qilib, bu yerda biz user ob'ektining sayHi usulini oldik.

Albatta, oldindan e'lon qilingan funksiyani usul sifatida ishlatishimiz mumkin, masalan:

let user = {
  // ...
};
 
// birinchi, funksiya e'lon qilinadi
function sayHi() {
  alert('Hello!');
}
 
// keyin usul sifatida qo'shiladi
user.sayHi = sayHi;
 
user.sayHi(); // Hello!

Ob'ektga yo'naltirilgan dasturlash

Kodimizni ob'ektlar yordamida yozganimizda, bu "ob'ektga yo'naltirilgan dasturlash" deb ataladi, qisqartmasi: “OOP”.

OOP katta narsa, o'ziga xos ilm-fan. To'g'ri ob'ektlarni qanday tanlash kerak? Ularning o'zaro aloqasini qanday tashkil qilish kerak? Bu arxitektura, va bu mavzu bo'yicha ko'plab ajoyib kitoblar mavjud, masalan, “Design Patterns: Elements of Reusable Object-Oriented Software” mualliflari E. Gamma, R. Helm, R. Johnson, J. Vissides yoki “Object-Oriented Analysis and Design with Applications” muallifi G. Booch va boshqalar.

Usulning qisqa sintaksisi

Ob'ekt literalida usullar uchun qisqa sintaksis mavjud:

// bu ob'ektlar bir xil
 
user = {
  sayHi: function () {
    alert('Hello');
  },
};
 
// qisqa sintaksis yaxshiroq ko'rinadi, to'g'rimi?
user = {
  sayHi() {
    // "sayHi: function(){...}" bilan bir xil
    alert('Hello');
  },
};

Ko'rib turganingizdek, biz "function" ni qoldirib, faqat sayHi() deb yozishimiz mumkin.

Aslida, bu yozuvlar to'liq bir xil emas. Ob'ekt vorisligi bilan bog'liq ba'zi nozik farqlar mavjud (keyinroq qoplanadi), lekin hozircha bu ahamiyatsiz. Deyarli barcha holatlarda, qisqa sintaksis afzal ko'riladi.

“this” usullarda

Ko'pincha ob'ekt usuli o'z vazifasini bajarish uchun ob'ektda saqlangan ma'lumotlarga kirish kerak bo'ladi.

Masalan, user.sayHi() ichidagi kod foydalanuvchining ismini bilishi kerak bo'lishi mumkin.

Ob'ektga kirish uchun usul this kalit so'zidan foydalanishi mumkin.

this ning qiymati “nuqtadan oldingi” ob'ekt bo'ladi, ya'ni usulni chaqirgan ob'ekt.

Masalan:

let user = {
  name: 'John',
  age: 30,
 
  sayHi() {
    // "this" - bu "joriy ob'ekt"
    alert(this.name);
  },
};
 
user.sayHi(); // John

Bu yerda user.sayHi() bajarilishi davomida this ning qiymati user bo'ladi.

Texnik jihatdan, ob'ektga thissiz ham kirish mumkin, uni tashqi o'zgaruvchi orqali ko'rsatish orqali:

let user = {
  name: 'John',
  age: 30,
 
  sayHi() {
    alert(user.name); // "user" o'rniga "this"
  },
};

…Lekin bunday kod ishonchsiz. Agar biz user ni boshqa o'zgaruvchiga ko'chirishga qaror qilsak, masalan, admin = user va user ni boshqa narsa bilan almashtirsak, u noto'g'ri ob'ektga murojaat qiladi.

Bu quyidagi misolda ko'rsatilgan:

let user = {
  name: 'John',
  age: 30,
 
  sayHi() {
    alert(user.name); // xatoga olib keladi
  },
};
 
let admin = user;
user = null; // ochiq qilish uchun qayta yozish
 
admin.sayHi(); // TypeError: Cannot read property 'name' of null

Agar biz alert ichida user.name o'rniga this.name ishlatganimizda, kod ishlagan bo'lardi.

“this” bog'lanmagan

JavaScript-da this kalit so'zi ko'pchilik boshqa dasturlash tillariga o'xshamaydi. Uni istalgan funksiyada ishlatish mumkin, hatto u ob'ektning usuli bo'lmasa ham.

Quyidagi misolda sintaksis xatosi yo'q:

function sayHi() {
  alert(this.name);
}

this ning qiymati ishlatish vaqtida baholanadi, kontekstga qarab.

Masalan, bu yerda bir xil funksiya ikki xil ob'ektga tayinlangan va chaqirilishda turli xil this qiymatiga ega:

let user = { name: 'John' };
let admin = { name: 'Admin' };
 
function sayHi() {
  alert(this.name);
}
 
// bir xil funksiya ikki ob'ektda ishlatiladi
user.f = sayHi;
admin.f = sayHi;
 
// bu chaqiruvlar turli xil this ga ega
// "this" funksiya ichida "nuqtadan oldingi ob'ekt" dir
user.f(); // John  (this == user)
admin.f(); // Admin  (this == admin)
 
admin['f'](); // Admin (nuqta yoki kvadrat qavs usulga kirishni ta'minlaydi – bu farq qilmaydi)

Qoidasi oddiy: agar obj.f() chaqirilsa, unda this chaqiruv vaqtida obj bo'ladi. Shunday qilib, yuqoridagi misolda user yoki admin bo'ladi.

Ob'ektsiz chaqirilganda: this == undefined

Biz funktsiyani umuman ob'ektsiz ham chaqirishimiz mumkin:

function sayHi() {
  alert(this);
}
 
sayHi(); // undefined

Bu holda, qat'iy rejimda this qiymati undefined bo'ladi. Agar biz this.name ga kirishga harakat qilsak, xato yuzaga keladi.

Qat'iy bo'lmagan rejimda, bunday holda this ning qiymati global ob'ekt bo'ladi (brauzerda window, keyinroq Global ob'ekt bo'limida buni muhokama qilamiz). Bu tarixiy xatti-harakatdir, "use strict" bu xatti-harakatni to'g'rilaydi.

Odatda bunday chaqiruv dasturlash xatosi hisoblanadi. Agar funksiyada this mavjud bo'lsa, u ob'ekt kontekstida chaqirilishini kutadi.

Bog'lanmagan this ning oqibatlari

Agar siz boshqa dasturlash tilidan kelgan bo'lsangiz, unda siz, ehtimol, "bog'langan this" g'oyasiga odatlangansiz, bu usullar ob'ektda aniqlanganda har doim this shu ob'ektni ko'rsatadi.

JavaScript-da this “erkin” bo'lib, uning qiymati chaqiruv vaqtida baholanadi va usul qaerda e'lon qilinganiga emas, balki "nuqtadan oldingi ob'ekt" ga bog'liq bo'ladi.

Run-time da baholanadigan this kontseptsiyasi ham ijobiy, ham salbiy tomonlarga ega. Bir tomondan, funksiya turli xil ob'ektlar uchun qayta ishlatilishi mumkin. Ikkinchi tomondan, bu qo'shimcha moslashuvchanlikka ega bo'lgan holatlarga olib kelishi mumkin, masalan, xatoga yo'l qo'ymaslik uchun this ning barcha kontekstlarda to'g'ri qiymatga ega ekanligiga ishonch hosil qilish kerak bo'ladi.

Muammolar

Bu erda ba'zi muammolar mavjud, ularni hal qilishingiz mumkin:

1. Ob'ektlarni tushunish:

Quyidagi kod nimani ko'rsatadi:

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

2. This ning qanday qiymatga teng bo'lishini toping:

Misol bilan o'ynang:

function makeUser() {
  return {
    name: 'John',
    ref: this,
  };
}
 
let user = makeUser();
 
alert(user.ref.name); // nimani ko'rsatadi?

3. So'zlar konvertori:

Ob'ekt usulidan foydalanib, string o'zgaruvchisini so'zlar ro'yxatiga bo'lish funksiyasini yarating:

let textObject = {
  text: 'Hello World!',
  splitText() {
    // bu yerga usulni yozing
  },
};
 
textObject.splitText(); // ["Hello", "World!"]

Ushbu sahifada

GitHubda tahrirlash