Obyektlar odatda foydalanuvchilar, buyurtmalar va boshqalar kabi real dunyo subyektlarini aks ettirish uchun yaratiladi:
let user = {
name: "John",
age: 30,
};
Va, haqiqiy dunyoda, foydalanuvchi harakat qilishi mumkin: xarid qilish vositasidan biror narsani tanlash, kirish, chiqish va hk.
Amallar JavaScript-da funktsiyadagi xususiyatlar bilan ifodalanadi.
Usul misollari
Boshlash uchun user ga salom aytishni orgataylik:
let user = {
name: "John",
age: 30
};
user.sayHi = function() {
alert("Salom!");
};
user.sayHi(); // Salom!
Bu yerda biz funktsiyani yaratish va uni obyektning user.sayHi xususiyatiga tayinlash uchun funktsiya ifodasini ishlatdik.
Keyin biz uni chaqira olamiz. Endi user gaplasha oladi!
Obyektning xususiyati bolgan funktsiya uning usuli deb nomlanadi.
Shunday qilib, bu yerda bizda user obyektining sayHi usuli bor.
Albatta, biz oldindan elon qilingan funktsiyalardan usul sifatida foydalanishimiz mumkin:
let user = {
// ...
};
// birinchi, e'lon qiling
function sayHi() {
alert("Hello!");
};
// keyin usul sifatida qo'shing
user.sayHi = sayHi;
user.sayHi(); // Salom!
Subyektlarni namoyish qilish uchun obyektlar yordamida kodimizni yozganimizda, bu obyektga yonaltirilgan dasturlash, qisqasi: OOP.
OOP bu katta narsa, oziga xos qiziqarli fan. Togri subyektlarni qanday tanlash kerak? Ularning ozaro tasirini qanday tashkil qilish kerak? Bu arxitektura va bu mavzu boyicha E.Gamma, R.Helm, R.Jonson, J.Vissidesning Dizayn naqshlari: qayta ishlatilishi mumkin bolgan obyektga yonaltirilgan dasturiy taminot elementlari yoki Obyektga yonaltirilgan tahlil va dizayn ilovalar G.Booch tomonidan yozilgan va boshqalar.
Usulni qisqartirish
Obyektdagi usullar uchun qisqa sintaksis mavjud:
// bu obyektlar ham xuddi shunday qiladi
user = {
sayHi: function() {
alert("Salom");
}
};
// usulni qisqartirish yaxshiroq ko'rinadi, to'g'rimi?
let user = {
sayHi() { // "sayHi: function()" bilan bir xil
alert("Salom");
}
};
Korsatilganidek, biz "function" ni qoldirib, faqat sayHi() yozishimiz mumkin.
Rostini aytsam, yozuvlar bir-biriga toliq oxshash emas. Obyektni meros qilib olish bilan bogliq nozik farqlar mavjud (keyinroq korib chiqiladi), ammo hozircha ularning ahamiyati yoq. Deyarli barcha hollarda qisqa sintaksisga ustunlik beriladi.
this usullarda
Obyekt usuli oz ishini bajarish uchun obyektda saqlangan malumotlarga kirish huquqiga ega bolishi odatiy holdir.
Masalan, user.sayHi() ichidagi kodga user nomi kerak bolishi mumkin.
Obyektga kirish uchun usul this kalit sozidan foydalanishi mumkin.
this qiymati bu usulni chaqirish uchun ishlatiladigan nuqta oldidagi obyekt.
Masalan:
let user = {
name: "John",
age: 30,
sayHi() {
// "this" is the "current object"
alert(this.name);
}
};
user.sayHi(); // John
Bu erda user.sayHi() bajarilishi paytida this qiymati user boladi.
Texnik jihatdan, this kalit sozisiz obyektga murojaat qilish mumkin, unga tashqi ozgaruvchan orqali murojaat qilish mumkin.
let user = {
name: "John",
age: 30,
sayHi() {
alert(user.name); // "user" "this" ning o'rniga
}
};
Ammo bunday kod ishonchli emas. Agar biz user ni boshqa ozgaruvchanga nusxalashga qaror qilsak, masalan, admin = user va user ni boshqa narsa bilan qayta yozsak, shunda u notogri obyektga murojaat qiladi.
Bu quyida korsatilgan:
let user = {
name: "John",
age: 30,
sayHi() {
alert( user.name ); // xatoga olib keladi
}
};
let admin = user;
user = null; // narsalarni aniq qilib ko'rsatish uchun qayta yozamiz
admin.sayHi(); // Voy! sayHi() ning ichida eski nom ishlatiladi! xato!
Agar biz alert ichida user.name orniga this.name dan foydalansak, u holda kod ishlaydi.
this bogliq emas
JavaScript-da, this kalit soz boshqa dasturlash tillarining aksariyatidan farq qiladi. Birinchidan, u har qanday funktsiyada ishlatilishi mumkin.
Bu kabi kodda sintaksis xato yoq:
function sayHi() {
alert( this.name );
}
this qiymati ish vaqtida baholanadi. Va u har qanday narsa bolishi mumkin.
Masalan, bir xil funktsiya turli xil obyektlardan chaqirilganda boshqacha this bolishi mumkin:
let user = { name: "John" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// ikkita obyektda bir xil funktsiyalardan foydalandik
user.f = sayHi;
admin.f = sayHi;
// chaqiruvlarda boshqacha this
// "this" - bu funktsiyaning ichida "nuqta oldidagi" obyekt
user.f(); // John (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (nuqta yoki to'rtburchak qavslar usuliga kirish uchun ishlatiladi - bu muhim emas)
Aslida, biz funktsiyani umuman obyektsiz chaqira olamiz:
function sayHi() {
alert(this);
}
sayHi(); // undefined
Bunday holda this qatiy rejimda undefined. Agar this.name ga kirishga harakat qilsak, xato boladi.
Qatiy bolmagan rejimda this qiymati global obyekt boladi (brauzerda window, biz keyinroq Global objekt bobida unga erishamiz. Bunday tarixiy xatti-harakatlarni tuzatish uchun, "use strict" dan foydalaning.
Iltimos, shuni yodda tutingki, odatda this ni obyektsiz ishlatiladigan funktsiya chaqiruvi odatiy emas, aksincha dasturiy xato. Agar funktsiya this ga ega bolsa, unda odatda obyekt kontekstida chaqirilishi kerak.
thisning oqibatlariAgar ilgari boshqa dasturlash tillarini organgan bolsangiz, unda siz bogliqthis goyasiga organib qolgansiz obyekt ichida aniqlangan usullar har doim oz obyektiga havolasini saqlaydi.
JavaScript-da this ozod, uning qiymati chaqiruv vaqtida baholanadi va usul qayerda elon qilinganiga bogliq emas, balki nuqta oldida nima bolganiga bogliq.
Ish vaqti tushunchasi this ijobiy va salbiy tomonlarga ega. Bir tomondan, funktsiyani turli xil obyektlar uchun qayta ishlatish mumkin. Boshqa tomondan, koproq moslashuvchanlik xatolar uchun joy ochadi.
Bu yerda bizning pozitsiyamiz ushbu tilni loyihalashtirish boyicha qarorning yaxshi yoki yomonligini baholash emas. U bilan qanday ishlashni, qanday foyda olish va muammolardan qanday qochish kerakligini organamiz.
Ichki dastur: havola turi
Ushbu bolim bazi murakkab vaziyatlarni yaxshiroq tushunish uchun murakkab mavzuni oz ichiga oladi.
Agar siz tezroq davom etmoqchi bolsangiz, uni otkazib yuborishingiz yoki qoldirishingiz mumkin.
Murakkab usul chaqiruvi this ning qiyamatini yoqotishi mumkin, masalan:
let user = {
name: "John",
hi() { alert(this.name); },
bye() { alert("Hayir"); }
};
user.hi(); // John (oddiy chaqiruv ishlaydi)
// endi nomiga qarab user.hi yoki user.bye ni chaqiramiz
(user.name == "John" ? user.hi : user.bye)(); // Xato!
Oxirgi satrda user.hi yoki user.bye ni tanlaydigan uchlik operatori mavjud. Bu holda natija user.hi boladi.
Usul darhol qavslar bilan chaqiriladi (). Ammo bu togri ishlamaydi!
Chaqiruv xatoga olib kelishini korishingiz mumkin, chunki chaqiruv ichidagi "this" qiymati undefined boladi.
Bu ishlaydi (obyekt nuqta usuli):
user.hi();
Bu ishlamaydi(baholangan usul):
(user.name == "John" ? user.hi : user.bye)(); // Xato!
Nima uchun? Agar nima uchun bunday bolishini tushunishni istasak, keling, obj.method() chaqiruvi qanday ishlashini korib chiqaylik.
Yaqindan qarab, obj.method() ifodasida ikkita operatsiyani korishimiz mumkin:
- Birinchi nuqta operator
'.'obyektning xususiyatini qaytaradiobj.method. - Keyin qavslar
()uni bajaradi.
Xosh, this haqidagi malumotlar birinchi qismdan ikkinchisiga qanday yetkaziladi?
Agar biz ushbu operatsiyalarni alohida satrlarga qoyadigan bolsak, unda this aniq yoqoladi:
let user = {
name: "John",
hi() { alert(this.name); }
}
// bo'linish va usulni ikki satrda chaqirish
let hi = user.hi;
hi(); // Xato, chunki this aniqlanmagan
Bu yerda hi = user.hi funktsiyani ozgaruvchanga qoyadi, songra oxirgi satrda u butunlay mustaqil boladi va shuning uchun this yoqoladi.
user.hi() chaqiruvi ishlash uchun JavaScript-da hiyla ishlatadi nuqta '.' funktsiyani emas, balki maxsus Reference Type qiymatini qaytaradi.
The Reference Type bu spetsifikatsiya turi dir. Biz uni aniq ishlata olmaymiz, lekin tilning ichida avtomatik ishlatiladi.
Reference Type qiymati uch qiymatli kombinatsiyadir (base, name, strict), bu erda:
basebu obyekt.namebu xususiyat.strictbu true agaruse strictamalda bosa
user.hi xususiyatiga kirish natijasi funktsiya emas, balki Reference Type qiymatidir. user.hi qatiy rejimda:
// Reference Type qiymati
user, "hi", true;
Reference Type-da qavslar () chaqirilganligida, ular obyekt va uning usuli haqida toliq malumot olishadi va togri this belgilashlari mumkin (= user shu holatda).
hi = user.hi tayinlash kabi boshqa har qanday operatsiya havola turini umuman bekor qiladi, user.hi (funktsiya) qiymatini oladi va uzatadi. Shunday qilib, keyingi har qanday operatsiya this ni yoqotadi.
Shunday qilib, natija sifatida, funktsiya togridan-togri obj.method() nuqta yoki kvadrat qavslar obj [' usuli ']() sintaksisidan foydalanilsa (ular bu erda bir xil narsa bajarishadi) boladi. Keyinchalik ushbu qollanmada biz ushbu muammoni hal qilishning turli xil usullarini organamiz, masalan func.bind().
Oq funktsiyalarida this yoq
Oq funktsiyalari maxsus: ularda ozlarining this yoq. Agar biz this ni oq funktsiyasi ichida ishlatsak, uning qiymati tashqi normal funktsiyadan olinadi.
Masalan, bu yerda arrow() tashqi user.sayHi() usulidan this ni ishlatadi:
let user = {
firstName: "Aziza",
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
},
};
user.sayHi(); // Aziza
Bu oq funktsiyalarining oziga xos xususiyati, biz aslida alohida this ga ega bolishni xohlamasligimiz, aksincha uni tashqi kontekstdan olishimiz foydalidir. Keyinchalik O'q funktsiyalarni takrorlayamiz bobida biz oq funktsiyalarini chuqurroq kirib boramiz.
Xulosa
- Obyekt xususiyatlarida saqlanadigan funktsiyalar usullar deb nomlanadi.
- Usullar obyektlarga
object.doSomething()kabi harakat qilish imkonini beradi. - Usullar obyektga
thisorqali murojaat qilishi mumkin.
this ning qiymati ish vaqtida aniqlanadi.
- Funktsiya elon qilinganda, u
thisdan foydalanishi mumkin, ammo funktsiya chaqirilgunchathisning qiymati bolmaydi. - Ushbu funktsiyani obyektlar ortasida nusxalash mumkin.
- Usul sintaksisida funktsiya chaqirilganda:
object.method(), chaqiruv paytidathisning qiymatiobjectdir.
Iltimos, oq funktsiyalari alohida ekanligini unutmang: ularda this yoq. Oq funktsiyaning ichida this ga elon qilinsa, uning qiymati tashqarida olinadi.
Izohlar
<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)