[ Web Proxy ]
URL:
Viewing: https://uz.javascript.info/object-methods [Back]  [Original]

Obyekt usullari, "this"
UZ

Ushbu ochiq manbali loyihani butun dunyo bo'ylab odamlar uchun taqdim etmoqchimiz.

Ushbu qo'llanmaning mazmuni sizning tilingizga tarjima qilishga yordam bering!

    Javascript.info saytidan qidirish:
    O'quv qo'llanmasidan qidiring:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    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!
    Obyektga yonaltirilgan dasturlash

    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.

    Boglanmagan thisning oqibatlari

    Agar 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

    Ilgor til imkoniyati

    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:

    1. Birinchi nuqta operator '.' obyektning xususiyatini qaytaradi obj.method.
    2. 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:

    • base bu obyekt.
    • name bu xususiyat.
    • strict bu true agar use strict amalda 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 this orqali murojaat qilishi mumkin.

    this ning qiymati ish vaqtida aniqlanadi.

    • Funktsiya elon qilinganda, u this dan foydalanishi mumkin, ammo funktsiya chaqirilguncha this ning qiymati bolmaydi.
    • Ushbu funktsiyani obyektlar ortasida nusxalash mumkin.
    • Usul sintaksisida funktsiya chaqirilganda: object.method(), chaqiruv paytida this ning qiymati object dir.

    Iltimos, oq funktsiyalari alohida ekanligini unutmang: ularda this yoq. Oq funktsiyaning ichida this ga elon qilinsa, uning qiymati tashqarida olinadi.

    Vazifalar

    Bu erda makeUser funktsiyasi obyektni qaytaradi.

    ref ga kirish natijasi qanday? Nima uchun?

    function makeUser() {
      return {
        name: "John",
        ref: this,
      };
    }
    
    let user = makeUser();
    
    alert(user.ref.name); // Natijasi nma?
    yechim

    Javob: xato

    Try it:

    function makeUser() {
      return {
        name: "John",
        ref: this,
      };
    }
    
    let user = makeUser();
    
    alert(user.ref.name); // Error: Cannot read property 'name' of undefined

    Buning sababi, this ni belgilaydigan qoidalar obyektlar soniga qarab bolmaydi.

    makeUser() ichidagi this" qiymati undefined, chunki u usul sifatida emas, balki funktsiya sifatida chaqirilgan.

    Obyektning ozi this ga tasir qilmaydi. this ning qiymati butun funktsiya uchun bitta, kod bloklari va obyektlar unga tasir qilmaydi.

    Shunday qilib, ref: bu aslida joriy funktsiyani this ni oladi.

    Qarama-qarshi holat:

    function makeUser() {
      return {
        name: "John",
        ref() {
          return this;
        }
      };
    }
    
    let user = makeUser();
    
    alert( user.ref().name ); // John

    Endi u ishlaydi, chunki user.ref() bu usul. Va this ning qiymati obyektga nuqtadan . oldin ornatiladi.

    Uch usul bilan calculator obyektini yarating:

    • read() ikkita qiymatni soraydi va ularni obyekt xususiyatlari sifatida saqlaydi.
    • sum() saqlangan qiymatlar yigindisini qaytaradi.
    • mul() saqlangan qiymatlarni kopaytiradi va natijani qaytaradi.
    let calculator = {
      // ... sizning kodingiz ...
    };
    
    calculator.read();
    alert(calculator.sum());
    alert(calculator.mul());

    Namoyishni ishga tushirish

    Sinovlar bilan sandbox-ni oching.

    yechim
    let calculator = {
      sum() {
        return this.a + this.b;
      },
    
      mul() {
        return this.a * this.b;
      },
    
      read() {
        this.a = +prompt("a?", 0);
        this.b = +prompt("b?", 0);
      },
    };
    
    calculator.read();
    alert(calculator.sum());
    alert(calculator.mul());

    Yechimni sandbox-dagi sinovlar bilan oching.

    Yuqoriga va pastga tushishga imkon beradigan ladder obyekti mavjud:

    let ladder = {
      step: 0,
      up() {
        this.step++;
      },
      down() {
        this.step--;
      },
      showStep: function () {
        // joriy qadamni ko'rsatadi
        alert(this.step);
      },
    };

    Endi, biz ketma-ket bir nechta chaqiruvlarni amalga oshirishimiz kerak bolsa, buni quyidagicha qilishimiz mumkin:

    ladder.up();
    ladder.up();
    ladder.down();
    ladder.showStep(); // 1

    Chaqiruvlarni zanjirlash uchun up, down va showStep kodlarini ozgartiring:

    ladder.up().up().down().showStep(); // 1

    Bunday yondashuv JavaScript kutubxonalarida keng qollaniladi.

    Sinovlar bilan sandbox-ni oching.

    yechim

    Yechim, har bir chaqiruvdan obyektning ozi qaytib keladi.

    let ladder = {
      step: 0,
      up() {
        this.step++;
        return this;
      },
      down() {
        this.step--;
        return this;
      },
      showStep() {
        alert( this.step );
        return this;
      }
    };
    
    ladder.up().up().down().up().down().showStep(); // 1

    Biz har bir satr uchun bitta chaqiruv yozishimiz mumkin. Uzoq zanjirlar uchun oqilishni oson qiladi:

    ladder.up().up().down().up().down().showStep(); // 1

    Yechimni sandbox-dagi sinovlar bilan oching.

    O'quv qo'llanma xaritasi

    Izohlar

    izoh berishdan oldin buni o'qing
    • Agar sizda nimani yaxshilash kerakligi haqida takliflaringiz bo'lsa - iltimos, GitHub muammosini yuboring yoki izoh berish o'rniga so'rov yuboring.
    • Agar siz maqolada biror narsani tushunolmasangiz - iltimos, batafsilroq ma'lumot bering.
    • Bir nechta so'z so'zlarini kiritish uchun <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)

    Web Proxy Viewer  |  New URL  |  Original Page