JavaScript'da 'this' Kontekstini O'zlashtirish
JavaScript'da 'this' Kontekstini O'zlashtirish va 'this'ning Bog'lanish Qoidalari
So'nggi yangilanish: 2024-12-14JavaScript dunyosida, this
kalit so'zi kuchli, ammo ko'pincha noto'g'ri tushunilgan tushunchadir. Bu har bir funksiya doirasida avtomatik ravishda belgilanadigan maxsus identifikator bo'lib, uning qiymati funksiya qanday chaqirilganiga qarab o'zgarishi mumkin. this
ni tushunish samarali, qayta ishlatiluvchi va saqlab turiluvchi JavaScript kodini yozish uchun juda muhimdir.
Ushbu keng qamrovli qo'llanma this
kalit so'zini tushuntirishga, uning turli kontekstlardagi xatti-harakatlarini o'rganishga, potensial xatolarni ochishga va undan foydalanish bo'yicha eng yaxshi amaliyotlarni taqdim etishga qaratilgan.
'this' nima?
JavaScript'da this
kalit so'zi obyektlarga dinamik ravishda bog'lanadigan havoladir. O'zgaruvchilardan farqli o'laroq, this
ning qat'iy qiymati yo'q; aksincha, uning qiymati funksiya qanday chaqirilganiga qarab aniqlanadi. Bu dinamik kontekst bog'lanishi this
ni ham kuchli, ham ba'zan chalkash qiladi.
Asosiy jihatdan, this
funksiyalarga ular chaqirilayotgan obyektga kirish imkonini beruvchi usuldir. U metodlarga obyektning xususiyatlari bilan o'zaro ta'sir qilish va ularni boshqarish imkonini beradi, bu esa JavaScript'da obyektga yo'naltirilgan dasturlash usullarini amalga oshirish imkonini beradi.
'this'ning Bog'lanish Qoidalari
this
qanday qiymat olishini tushunish uchun, this
ning bog'lanishini aniqlaydigan to'rtta asosiy qoidani bilishimiz kerak:
- Standart Bog'lanish: Funksiya global doirada chaqirilganda.
- Yashirin Bog'lanish: Funksiya obyektning metodi sifatida chaqirilganda.
- Aniq Bog'lanish:
call()
,apply()
yokibind()
metodlari ishlatilganda. - Yangi Bog'lanish: Funksiya
new
kalit so'zi bilan konstruktor sifatida ishlatilganda.
Keling, bu kontekstlarning har birini batafsil ko'rib chiqaylik.
Global Kontekst
Global bajarish kontekstida (har qanday funksiyadan tashqarida), this
global obyektga ishora qiladi. Brauzer muhitida global obyekt window
dir. Node.js'da esa bu global
dir.
Misol:
console.log(this === window); // brauzerda true
var globalVar = "Men global o'zgaruvchiman";
console.log(this.globalVar); // "Men global o'zgaruvchiman"
function createGlobal() {
this.newGlobalVar = "Men yangi global o'zgaruvchiman";
}
createGlobal();
console.log(window.newGlobalVar); // "Men yangi global o'zgaruvchiman"
Shuni esda tutish muhimki, modullarda (import
/export
ishlatilganda), yuqori darajadagi this
global obyekt emas, balki undefined
dir.
Funksiya Konteksti
Funksiya ichidagi this
ning qiymati funksiya qanday chaqirilganiga bog'liq. Bu ko'p dasturchilar uchun JavaScript'ning eng chalkash jihatlaridan biridir.
function showThis() {
console.log(this);
}
// Oddiy funksiya chaqiruvi
showThis(); // qat'iy bo'lmagan rejimda window yoki qat'iy rejimda undefined
// Obyekt metodi sifatida
const obj = { method: showThis };
obj.method(); // obj
// call yordamida this ni o'rnatish
showThis.call({ custom: 'context' }); // { custom: 'context' }
// Konstruktor sifatida
new showThis(); // {} (yangi obyekt)
Bu turli chaqiruv usullarini tushunish JavaScript'da this
ni o'zlashtirishning kalitidir.
Obyekt Metodi Konteksti
Funksiya obyektning metodi sifatida chaqirilganda, this
metod chaqirilgan obyektga o'rnatiladi. Bu xatti-harakat metodlarga obyektning xususiyatlariga kirish va ularni boshqarish imkonini beradi.
const shaxs = {
ism: 'Alisher',
salomlash: function() {
console.log(`Salom, mening ismim ${this.ism}`);
},
do'st: {
ism: 'Bobur',
salomlash: function() {
console.log(`Salom, mening ismim ${this.ism}`);
}
}
};
shaxs.salomlash(); // "Salom, mening ismim Alisher"
shaxs.do'st.salomlash(); // "Salom, mening ismim Bobur"
// Ammo ehtiyot bo'ling:
const salomlashFunksiyasi = shaxs.salomlash;
salomlashFunksiyasi(); // "Salom, mening ismim undefined" (qat'iy bo'lmagan rejimda)
Bu oxirgi misol keng tarqalgan xatoni ko'rsatadi: metod o'zgaruvchiga tayinlanganda va keyin chaqirilganda, u o'zining asl this
kontekstini yo'qotadi.
Konstruktor Konteksti
Funksiya konstruktor sifatida ishlatilganda (new
kalit so'zi bilan chaqirilganda), this
yangi yaratilgan obyektga bog'lanadi. Bu bog'lanish funksiya tanasi bajarilishidan oldin sodir bo'ladi.
function Shaxs(ism, yosh) {
this.ism = ism;
this.yosh = yosh;
this.salomlash = function() {
console.log(`Salom, men ${this.ism}man va ${this.yosh} yoshdaman.`);
};
}
const alisher = new Shaxs('Alisher', 30);
alisher.salomlash(); // "Salom, men Alisherman va 30 yoshdaman."
// 'new' ni unutsak nima bo'ladi?
const bobur = Shaxs('Bobur', 25); // Xato! 'this' global obyekt yoki qat'iy rejimda undefined bo'ladi
console.log(bobur); // undefined
console.log(window.ism); // "Bobur" (qat'iy bo'lmagan rejimda, brauzer muhitida)
Bu misol konstruktor funksiyalar bilan obyektlar yaratishda nima uchun new
dan foydalanish muhimligini ko'rsatadi.
Hodisa Ishlovchilari
Brauzer muhitlarida, funksiya hodisa ishlovchisi sifatida ishlatilganda, this
hodisani ishga tushirgan DOM elementiga o'rnatiladi. Bu xatti-harakat turli brauzerlar orasida bir xil va ishlovchi ichida elementga qulay kirish imkonini beradi.
document.querySelector('button').addEventListener('click', function() {
console.log(this); // Tugma elementi
this.textContent = 'Bosildi!';
});
// Ammo o'q funksiyalari boshqacha ishlaydi:
document.querySelector('button').addEventListener('click', () => {
console.log(this); // Window (yoki global obyekt)
});
Oddiy funksiyalar va o'q funksiyalari o'rtasidagi bu farqni tushunish DOM hodisalari bilan ishlashda juda muhimdir.
O'q Funksiyalari va 'this'
ES6 da taqdim etilgan o'q funksiyalari this
ni oddiy funksiyalardan farqli ravishda boshqaradi. Ular o'zlarining this
ini bog'lamaydilar, balki o'rab turgan doiradan this
ni meros qilib oladilar. Bu xatti-harakat, leksik this
bog'lanishi deb ataladi, va u ham kuchli, ham murakkab bo'lishi mumkin.
const obj = {
nom: 'Mening Obyektim',
oddiyFunksiya: function() {
console.log(this.nom);
},
oqFunksiya: () => {
console.log(this.nom);
},
kechiktirilganOddiy: function() {
setTimeout(function() {
console.log(this.nom);
}, 100);
},
kechiktirilganOq: function() {
setTimeout(() => {
console.log(this.nom);
}, 100);
}
};
obj.oddiyFunksiya(); // "Mening Obyektim"
obj.oqFunksiya(); // undefined (this global obyekt)
obj.kechiktirilganOddiy(); // undefined (this global obyekt)
obj.kechiktirilganOq(); // "Mening Obyektim"
Bu misol o'q funksiyalarining qayta chaqiruvlarda this
kontekstini yo'qotish muammosini qanday hal qilishini ko'rsatadi, ammo ular ehtiyotsiz ishlatilganda kutilmagan natijalarga olib kelishi mumkinligini ham ko'rsatadi.
Aniq Bog'lanish
JavaScript this
ning qiymatini aniq o'rnatish uchun metodlar taqdim etadi: call()
, apply()
va bind()
. Bu metodlar funksiyani qanday aniqlangan yoki qayerdan chaqirilganidan qat'i nazar, belgilangan this
qiymati bilan chaqirish imkonini beradi.
function salomlash(salom, tinish) {
console.log(`${salom}, ${this.ism}${tinish}`);
}
const shaxs = { ism: 'Alisher' };
// call dan foydalanish
salomlash.call(shaxs, 'Salom', '!'); // "Salom, Alisher!"
// apply dan foydalanish
salomlash.apply(shaxs, ['Assalom', '?']); // "Assalom, Alisher?"
// bind dan foydalanish
const bog'langanSalomlash = salomlash.bind(shaxs);
bog'langanSalomlash('Hayrli kun', '.'); // "Hayrli kun, Alisher."
// oldindan o'rnatilgan argumentlar bilan bind
const salomAytAlisher = salomlash.bind(shaxs, 'Salom');
salomAytAlisher('!!'); // "Salom, Alisher!!"
Bu metodlarni tushunish ilg'or JavaScript dasturlash uchun juda muhim, ayniqsa qayta chaqiruvlar va hodisa ishlovchilari bilan ishlashda.
Yashirin Bog'lanish
Yashirin bog'lanish metod obyektda chaqirilganda sodir bo'ladi. Bu holda, this
avtomatik ravishda metod chaqirilgan obyektga bog'lanadi.
const shaxs = {
ism: 'Alisher',
yosh: 30,
salomlash() {
console.log(`Salom, men ${this.ism}man va ${this.yosh} yoshdaman.`);
}
};
shaxs.salomlash(); // "Salom, men Alisherman va 30 yoshdaman."
// Ammo buni qilsak nima bo'ladi?
const salomlash = shaxs.salomlash;
salomlash(); // "Salom, men undefinedman va undefined yoshdaman."
Oxirgi misol yashirin bog'lanish metod o'zgaruvchiga tayinlanganda va keyin chaqirilganda qanday "yo'qolishi" mumkinligini ko'rsatadi.
Leksik 'this'
Leksik this
o'q funksiyalarining this
kalit so'zini qanday boshqarishiga ishora qiladi. Oddiy funksiyalardan farqli o'laroq, o'q funksiyalarining o'z this
konteksti yo'q.Buning o'rniga, ular o'rab turgan doiradan this
ni meros qilib oladilar.
const obj = {
nom: 'Mening Obyektim',
oddiyMetod() {
console.log(this.nom);
return () => {
console.log(this.nom);
};
},
oqMetod: () => {
console.log(this.nom);
}
};
obj.oddiyMetod()(); // "Mening Obyektim" (ikki marta)
obj.oqMetod(); // undefined
Bu xatti-harakat o'q funksiyalarini qayta chaqiruvlar va this
kontekstini saqlab qolish kerak bo'lgan metodlar uchun ayniqsa foydali qiladi.
Klasslarda 'this'
ES6 da class
sintaksisi kiritilishi bilan, this
konstruktor funksiyalardagi kabi ishlaydi, ammo ba'zi muhim farqlar bilan:
class Shaxs {
constructor(ism) {
this.ism = ism;
}
salomlash() {
console.log(`Salom, men ${this.ism}man`);
}
static salomAyt() {
console.log(`Salom! ${this.name}`);
}
}
const alisher = new Shaxs('Alisher');
alisher.salomlash(); // "Salom, men Alisherman"
Shaxs.salomAyt(); // "Salom! Shaxs"
Klass metodlarida, this
klass namunasiga ishora qiladi. Statik metodlarda esa, this
klassning o'ziga ishora qiladi.
Umumiy Xatolar
- Qayta chaqiruvlarda
this
ni yo'qotish:
const obj = {
nom: 'Mening Obyektim',
kechiktirilganSalomlash() {
setTimeout(function() {
console.log(this.nom); // undefined
}, 100);
}
};
obj.kechiktirilganSalomlash();
- Global
this
ni obyekt metodiningthis
i deb o'ylash:
const obj = {
nom: 'Mening Obyektim',
salomlash: () => {
console.log(this.nom); // undefined
}
};
obj.salomlash();
- Konstruktor funksiyalar bilan
new
ishlatishni unutish:
function Shaxs(ism) {
this.ism = ism;
}
const alisher = Shaxs('Alisher'); // Xato! 'new Shaxs('Alisher')' bo'lishi kerak
console.log(alisher); // undefined
console.log(window.ism); // 'Alisher' (qat'iy bo'lmagan rejimda)
Eng Yaxshi Amaliyotlar
this
kontekstini saqlash uchun qayta chaqiruvlarda o'q funksiyalaridan foydalaning:
const obj = {
nom: 'Mening Obyektim',
kechiktirilganSalomlash() {
setTimeout(() => {
console.log(this.nom); // 'Mening Obyektim'
}, 100);
}
};
- Global doirada
this
dan foydalanishdan qoching. - Funksiya uslubingizda izchil bo'ling (obyektda barcha oddiy funksiyalarni yoki barcha o'q funksiyalarini ishlating).
this
ni aniq o'rnatish kerak bo'lgandabind()
,call()
yokiapply()
dan foydalaning.- Metodlarga ega obyektlar yaratish uchun klasslardan foydalaning, chunki ular aniqroq tuzilishni ta'minlaydi va
this
ni yanada bashorat qilinadigan tarzda boshqaradi.
Ilg'or 'this' Texnikalari
Metod Qarz Olish
Siz call()
yoki apply()
yordamida bir obyektdan metodlarni "qarz olib" boshqa obyekt bilan ishlatishingiz mumkin:
const shaxs = {
to'liqIsm() {
return `${this.ism} ${this.familiya}`;
}
};
const john = {
ism: 'John',
familiya: 'Doe'
};
console.log(shaxs.to'liqIsm.call(john)); // "John Doe"
Qisman Qo'llash
Siz bind()
dan ba'zi argumentlari oldindan o'rnatilgan yangi funksiya yaratish uchun foydalanishingiz mumkin:
function ko'paytir(x, y) {
return x * y;
}
const ikkilantir = ko'paytir.bind(null, 2);
console.log(ikkilantir(5)); // 10
Qat'iy Rejimda 'this'
ECMAScript 5 da kiritilgan qat'iy rejim this
ning ba'zi xatti-harakatlarini o'zgartiradi:
- Global doirada,
this
global obyekt o'rnigaundefined
bo'ladi. - Funksiya kontekstsiz chaqirilganda (ya'ni, metod sifatida emas yoki
call
/apply
bilan emas),this
global obyekt o'rnigaundefined
bo'ladi.
'use strict';
function showThis() {
console.log(this);
}
showThis(); // undefined
'this'ni Disk Raskadrovka Qilish
this
muammolarini disk raskadrovka qilishda:
- Kodingizning turli nuqtalarida
console.log(this)
dan foydalaning. this
qiymatini ish vaqtida tekshirish uchun disk raskadrovka vositasidan foydalaning.- Funksiya qaysi kontekstda chaqirilayotganini bilishingizdan xabardor bo'ling.
Tez-tez So'raladigan Savollar
- Savol: Nima uchun mening funksiyamdagi
this
undefined? Javob: Bu ko'pincha qat'iy rejimda funksiya kontekstsiz chaqirilganda sodir bo'ladi. Funksiyani obyekt metodi sifatida chaqirayotganingizga yoki kontekstni o'rnatish uchuncall()
,apply()
yokibind()
dan foydalanayotganingizga ishonch hosil qiling. - Savol: Qayta chaqiruvda
this
ni qanday saqlash mumkin? Javob: Siz o'rab turgan doiradanthis
ni meros qilib oladigan o'q funksiyasidan foydalanishingiz yoki qayta chaqiruv uchunthis
ni aniq o'rnatish uchunbind()
dan foydalanishingiz mumkin. - Savol: Nima uchun
this
o'q funksiyalarida boshqacha ishlaydi? Javob: O'q funksiyalarining o'zthis
bog'lanishi yo'q. Ularthis
ni o'rab turgan leksik doiradan meros qilib oladilar, bu qayta chaqiruvlar uchun foydali bo'lishi mumkin, lekin obyekt metodlari sifatida ishlatilganda kutilmagan xatti-harakatga olib kelishi mumkin.
Qo'shimcha Manbalar
- MDN Web Docs: this
- JavaScript.info: Obyekt metodlari, "this"
- You Don't Know JS: this & Object Prototypes
- JavaScript'da this ni Aniqlik bilan Tushunish va Uni O'zlashtirish
- JavaScript'da 'this' ning Oddiy Qoidalari
- JavaScript: The Definitive Guide - 8-bob: Funksiyalar
- Eloquent JavaScript - 6-bob: Obyektlarning Maxfiy Hayoti