IlmHamroh
JavaScript Full-stack/10-qism. JavaScript chuqur19/65-dars17 daqiqa
Mundarija (28)

JavaScript execution context va call stack: kod ichidan qanday bajariladi

Qisqacha: Execution context (bajarilish konteksti) — JavaScript kodni bajarayotganda yuritadigan "ish varag'i": qaysi o'zgaruvchilar bor, ular qanday qiymatda va tashqi muhit qaysi. Dastur boshida bitta global kontekst yaratiladi, keyin har funksiya chaqiruvi o'z yangi kontekstini oladi. Har kontekst ikki bosqichdan o'tadi — avval yaratish (e'lonlar ro'yxatga olinadi), keyin bajarish (qatorma-qator). Kontekstlar chaqiruvlar stekiga (call stack) joylanadi: tepadagisi bajariladi, tugagach olib tashlanadi.

Bu darsda

  • Execution context nima ekanini va unda nimalar saqlanishini tushuntira olasiz.
  • Global va funksiya kontekstini farqlaysiz.
  • Yaratish va bajarish bosqichlarida nima bo'lishini qadamma-qadam ayta olasiz.
  • Kod bajarilayotganda call stack'ni qog'ozda chiza olasiz va stack trace'ni kontekstlar ro'yxati sifatida o'qiysiz.
  • vazifalar da bitta bosish qaysi funksiyalar zanjiridan o'tishini DevTools'da ko'rasiz.

Oldin bilishingiz kerak: Rekursiya asoslari, DevTools bilan debug qilish, Scope asoslari, Stack trace va xato turlari.

1. Nega bu kerak?

08-qismda bir nechta "g'alati" qoidalarni ko'rgan edik:

Har birini alohida yodlash mumkin. Lekin ularning hammasi bitta mexanizmdan kelib chiqadi. Shu mexanizmni tushunsangiz, to'rttala qoida "o'z-o'zidan" ma'lum bo'ladi. Bugun va keyingi uch darsda aynan shu mexanizmni ochamiz: execution context, scope zanjiri, hoisting va TDZ.

Hayotdan o'xshatish. «Bahor» oshxonasida har buyurtma uchun alohida varaq yoziladi: qaysi stol, nima taom, nechta, izoh. Rustam aka varaqlarni ilgichga birin-ketin ilib boradi va doim eng ustidagi varaq bo'yicha ishlaydi. Tayyor bo'lgach, varaqni olib tashlaydi va pastdagisiga qaytadi. Ikki stol bir xil osh buyursa ham — ikkita alohida varaq: biri 2 ta, biri 5 ta.

JavaScript'da varaq — execution context, ilgich — call stack.

2. Execution context nima?

2.1 Ta'rif

Bajarilish konteksti (execution context) — JavaScript hozir bajarayotgan kod uchun yuritadigan ichki yozuv. Unda uchta narsa bor:

Qism Nima saqlanadi Qaysi darsda chuqur
O'zgaruvchilar Parametrlar, let, const, var, funksiyalar — nomi va qiymati shu dars
Tashqi havola Topilmagan nomni qayerdan qidirish Leksik scope
this Maxsus so'zning qiymati this

Bu yozuvni kodda ko'rmaysiz va unga murojaat qila olmaysiz. U JavaScript dvigatelining ichida yashaydi. Lekin uning izlari hamma joyda: DevTools'dagi Scope bo'limi — joriy kontekstning o'zgaruvchilari, Call Stack — kontekstlar ro'yxati (DevTools bilan debug qilish).

Ikki atamani adashtirmang. Scope — kod matnidagi hudud: qaysi nom qayerda ko'rinadi. U kod yozilganda belgilanadi. Kontekst — bajarilish paytidagi yozuv. U funksiya chaqirilganda yaratiladi va tugaganda yo'qoladi. Bitta funksiyaning scope'i bitta, kontekstlari esa har chaqiruvda yangi.

2.2 Ikki asosiy tur

Global kontekst — dastur boshlanganda yaratiladi, faqat bitta. Unda fayl darajasidagi nomlar yashaydi: yuqori darajadagi const, let va funksiyalar.

Funksiya konteksti — har funksiya chaqiruvida yangisi yaratiladi. Funksiyani e'lon qilish kontekst yaratmaydi — faqat chaqirish.

Maslahat: Node'dagi .mjs fayl va brauzerdagi <script type="module"> da faylning yuqori darajasi — modul konteksti. U global kontekstdan bir qavat ichkarida turadi. Bu darsdagi misollar uchun farqi yo'q — biz ikkalasini "global" deymiz. Farqini Global obyekt va globalThis va modullar darslarida ko'ramiz. eval uchun ham alohida kontekst bor, lekin eval ishlatilmaydi (eval va new Function).

Tekshirib ko'ring: Faylda 5 ta funksiya e'lon qilingan, ulardan bittasi 3 marta chaqirildi. Dastur davomida nechta kontekst yaratildi?

Javob

4 ta: bitta global va uchta funksiya konteksti. E'lon qilingan, lekin chaqirilmagan to'rtta funksiya hech qanday kontekst yaratmaydi. Bir funksiyaning uch chaqiruvi esa uchta alohida kontekst — har birida o'z o'zgaruvchilari.

3. Ikki bosqich: yaratish va bajarish

3.1 Bosqichlar

Kontekst bir zumda "tayyor" bo'lmaydi. Har kontekst ikki bosqichdan o'tadi:

  1. Yaratish bosqichi (creation phase). Kod hali bajarilmaydi. JavaScript funksiya tanasini (yoki butun faylni) bir marta ko'zdan kechirib, barcha e'lonlarni ro'yxatga oladi:
    • parametrlar — chaqiruvdagi argumentlar bilan;
    • function e'lonlari — to'liq funksiya bilan;
    • var — undefined bilan;
    • let va const — nom yoziladi, lekin qiymat yo'q ("tayyor emas" belgisi bilan).
  2. Bajarish bosqichi (execution phase). Endi kod yuqoridan pastga, qatorma-qator bajariladi. Tayinlashlar qiymat beradi, chaqiruvlar yangi kontekst ochadi.

Maktab jurnali o'xshatishini eslang (var darsi): o'quv yili boshida o'qituvchi jurnalga barcha ismlarni yozadi — bu yaratish. Baholar esa dars bo'lganda qo'yiladi — bu bajarish.

3.2 Isbot

Yaratish bosqichini o'z ko'zimiz bilan ko'ramiz. Funksiya boshida — hali hech bir qator bajarilmasdan — nomlarga qaraymiz:

js
function chekYoz(soni) {
  console.log(soni); // 2
  console.log(typeof hisobla); // function
  console.log(izoh); // undefined

  var izoh = "Rahmat!";
  function hisobla() {
    return 35000 * soni;
  }

  return `${hisobla()} so'm. ${izoh}`;
}

console.log(chekYoz(2)); // 70000 so'm. Rahmat!

Birinchi uchta console.log funksiyaning birinchi qatorlari. Lekin:

  • soni allaqachon 2 — parametr yaratish bosqichida to'ldirildi.
  • hisobla allaqachon funksiya — u 7-qatorda e'lon qilingan bo'lsa ham.
  • izoh mavjud, lekin undefined — "Rahmat!" faqat 6-qatorga yetganda beriladi.

Uchalasi ham bitta sababdan: kod bajarilishidan oldin yaratish bosqichi o'tdi. Endi let bilan:

js
function chekYoz() {
  console.log(izoh);
  let izoh = "Rahmat!";
}

chekYoz();
text
ReferenceError: Cannot access 'izoh' before initialization

Tarjimasi: "izoh ga boshlang'ich qiymat berilishidan oldin murojaat qilib bo'lmaydi". Nom ro'yxatda bor — aks holda xabar izoh is not defined bo'lardi. Lekin qiymati yo'q, tegish taqiqlangan. Bu holatning nomi — TDZ, uni Temporal Dead Zone darsida, e'lonlarning "ko'tarilishi"ni esa Hoisting darsida to'liq ko'ramiz.

3.3 Global kontekst ham ikki bosqichli

Yaratish bosqichi faqat funksiyalarda emas. Global kontekst ham avval butun faylni ko'zdan kechiradi, keyin bajaradi:

js
console.log(chegirmaQol(100000)); // 90000

function chegirmaQol(summa) {
  return summa - summa / 10;
}

Funksiya e'lon qilish darsida bu "hiyla"ni ko'rgan edik va "kod yuqoridan pastga bajariladi" qoidasi bilan qanday kelishishini so'ragan edik. Endi javob aniq. Ikkala gap ham rost, faqat ular ikki xil bosqich haqida. Yaratish bosqichida chegirmaQol to'liq ro'yxatga olindi. Bajarish bosqichi esa haqiqatan 1-qatordan boshlandi — va shu paytda funksiya allaqachon tayyor edi.

Shuning uchun vazifalar.js da tinglovchilar faylning oxirida turgani muhim emas: ular chaqiradigan render, vazifaQosh va boshqalar yaratish bosqichidayoq tayyor bo'ladi. Lekin const holat — yo'q. Bu farqni Hoisting darsida vazifalar ning o'zida sinab ko'ramiz.

Kontekstning butun umri — bitta sxemada. Strelkalar bo'ylab o'qing:

flowchart LR
  A["Chaqiruv:<br/>chekYoz(2)"] --> B["Yaratish:<br/>nomlar ro'yxatga"]
  B --> C["Stek tepasiga<br/>qo'yiladi"]
  C --> D["Bajarish:<br/>qatorma-qator"]
  D -- "ichkarida chaqiruv" --> A
  D -- "return yoki oxiri" --> E["Stekdan<br/>olib tashlanadi"]
  E --> F["Chaqirgan joyga<br/>qaytish"]

Ichkaridagi chaqiruv o'qi orqaga — A ga — qaytadi: yangi kontekst ham xuddi shu yo'ldan o'tadi va eskisining ustiga qo'yiladi.

Tekshirib ko'ring: Yaratish bosqichida const narx = 35000; qatoridan nima ro'yxatga olinadi — nommi, qiymatmi yoki ikkalasi?

Javob

Faqat nom — narx, "tayyor emas" belgisi bilan. 35000 qiymati faqat bajarish bosqichida, kod shu qatorga yetganda beriladi. Shuning uchun undan oldin narx ni o'qish ReferenceError beradi.

4. Call stack: kontekstlar taxlami

4.1 Qadamma-qadam

Chaqiruvlar steki (call stack) — Rekursiya darsidan tanish: hozir bajarilayotgan chaqiruvlar ro'yxati, likoplar taxlamidek. Endi aniqroq ayta olamiz: stekning har qavati — bitta execution context.

Rekursiyasiz, oddiy zanjirda kuzatamiz. Keyingi tugmasini bosing. O'ngdagi "Chaqiruvlar steki" ga va har yangi kontekstdagi o'zgaruvchilarga qarang — avval "tayyor emas", keyin qiymat:

Uchta kuzatish:

  • Bir xil nom — ikki o'zgaruvchi. chekYoz da ham, narxniOl da ham taom bor. Ular ikki kontekstda ikki alohida o'zgaruvchi.
  • Kutish. chekYoz 7-qatorda to'xtab turdi. U o'chmadi, stekdan chiqmadi — faqat ustiga boshqa kontekst qo'yildi.
  • Tugash — yo'qolish. narxniOl tugagach, uning menyu si ham yo'qoldi. Kontekst o'zgaruvchilari shu kontekst bilan birga yashaydi.

Tekshirib ko'ring: narxniOl tugagach, uning menyu o'zgaruvchisini chekYoz ichidan o'qish mumkinmi?

Javob

Yo'q. menyu faqat narxniOl kontekstida yashadi va u stekdan chiqishi bilan yo'qoldi. chekYoz ga faqat qaytarilgan qiymat — 35000 — keldi. Funksiyadan ma'lumot olib chiqishning yo'li — return.

4.2 Har chaqiruv — yangi kontekst

Bir funksiyani ketma-ket ikki marta chaqiramiz:

js
function stolHisobi(stol, soni) {
  const jami = soni * 35000;
  console.log(`${stol}-stol: ${jami}`);
}

stolHisobi(3, 2);
stolHisobi(7, 5);

Konsolda:

text
3-stol: 70000
7-stol: 175000

Ikkinchi chaqiruvda jami birinchisini "eslamaydi". Birinchi kontekst stekdan chiqqanda uning jami si ham ketdi. Ikkinchi chaqiruv yangi varaqdan boshladi. Scope asoslari darsidagi "har chaqiruvda — yangi o'zgaruvchilar" qoidasining ichki sababi shu.

Rekursiyada bir funksiyaning bir nechta konteksti stekda bir vaqtda turadi. faktorial(3) da uchta kontekst — har birida o'z n i: 3, 2, 1 (Rekursiya asoslari). Ular bir-biriga xalaqit bermaydi, chunki har biri alohida varaq.

O'zingiz to'ldiring: faktorial(5) chaqirilganda stekda bir vaqtda eng ko'pi bilan ta faktorial konteksti bo'ladi.

5. Stack trace — stekning surati

5.1 Xato paytidagi stek

Stack trace darsida at ... qatorlarini o'qishni o'rgandik. Endi ularning ma'nosi aniq: stack trace — xato yuz bergan paytdagi call stack'ning surati. Har at qatori — bitta kontekst. Eng tepadagisi — xato chiqqan kontekst.

chek.js:

js
const menyu = {
  osh: { narx: 35000 },
  manti: { narx: 30000 },
};

function narxniOl(taom) {
  return menyu[taom].narx;
}

function chekYoz(taom, soni) {
  const narx = narxniOl(taom);
  return `${taom} × ${soni}: ${narx * soni} so'm`;
}

function buyurtmaBer(taom, soni) {
  console.log(chekYoz(taom, soni));
}

buyurtmaBer("osh", 2);
buyurtmaBer("palov", 1);

node chek.js — Node 24 (C:\... — yo'l qisqartirildi):

text
osh × 2: 70000 so'm
C:\...\10\chek.js:7
  return menyu[taom].narx;
                     ^

TypeError: Cannot read properties of undefined (reading 'narx')
    at narxniOl (C:\...\10\chek.js:7:22)
    at chekYoz (C:\...\10\chek.js:11:16)
    at buyurtmaBer (C:\...\10\chek.js:16:15)
    at Object.<anonymous> (C:\...\10\chek.js:20:1)
    at Module._compile (node:internal/modules/cjs/loader:1929:14)
    at Object..js (node:internal/modules/cjs/loader:2060:10)
    at Module.load (node:internal/modules/cjs/loader:1651:32)
    at Module._load (node:internal/modules/cjs/loader:1443:12)
    at wrapModuleLoad (node:internal/modules/cjs/loader:261:19)
    at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)

Node.js v24.21.0

at qatorlarini pastdan tepaga o'qing — stek shunday o'sgan:

at qatori Kontekst Qayerda to'xtab turibdi
Object.<anonymous> …:20:1 global (fayl) 20-qator: buyurtmaBer("palov", 1)
buyurtmaBer …:16:15 buyurtmaBer("palov", 1) 16-qator: chekYoz ni kutyapti
chekYoz …:11:16 chekYoz("palov", 1) 11-qator: narxniOl ni kutyapti
narxniOl …:7:22 narxniOl("palov") 7-qator: xato shu yerda

Har qatordagi raqam — o'sha kontekst to'xtab turgan joy: kimni kutayotgani. Birinchi buyurtmaBer("osh", 2) surati yo'q — u xatodan oldin tugab, stekdan chiqib bo'lgan edi. Pastdagi node:internal qatorlari — Node'ning o'z konteksti: u faylingizni ishga tushirgan kod. Node odatda faqat 10 ta qatorni ko'rsatadi.

5.2 Jonli stek

Xato bo'lmasa ham stekni ko'rish mumkin. DevTools bilan debug qilish darsida o'rganganingiz — Call Stack bo'limi: breakpoint'da to'xtaganda u joriy stekni ko'rsatadi. Ro'yxatdagi qatorni bossangiz, Scope bo'limi o'sha kontekstning o'zgaruvchilarini ko'rsatadi. Ya'ni DevTools stekdagi har varaqni varaqlab ko'rishga imkon beradi. Buni «Vazifalar qadami» da vazifalar ilovasida qilasiz.

Tekshirib ko'ring: Stack trace'da at chekYoz (…chek.js:11:16) qatori bor. Xato 11-qatordami?

Javob

Yo'q. Xato 7-qatorda — eng tepadagi narxniOl da. chekYoz 11-qatorda to'xtab turgan edi: u narxniOl dan javob kutayotgan edi. Stack trace'dagi pastki qatorlar — xato joyi emas, unga olib kelgan yo'l.

6. Bitta stek — bir vaqtda bitta ish

JavaScript'da call stack bitta. Demak bir paytda faqat bitta kontekst — tepadagisi — bajariladi. Bu bir oqimli (single-threaded) bajarilish deyiladi.

Oqibati muhim. Tepadagi funksiya uzoq ishlasa — masalan, million elementli massivni aylansa — undan pastdagilar ham, boshqa hamma ish ham kutadi. Brauzerda bu sahifaning "qotishi"dir: tugma bosilishi, matn yozish, animatsiya — hammasi stek bo'shashini kutadi. Rustam aka bitta katta to'y oshi bilan band bo'lsa, ilgichdagi kichik buyurtmalar ham kutib turadi.

Unda tarmoqdan javob kutish yoki taymer qanday ishlaydi? Ular stekdan tashqarida kutadi va tayyor bo'lgach, stekka navbat bilan qo'yiladi. Bu mexanizm — event loop, uni 11-qismda, Event loop darsida o'rganamiz — hozir bilish shart emas. Hozircha bitta qoida: call stack'dagi ish tugamaguncha, keyingisi boshlanmaydi.

Tekshirib ko'ring: Tugma bosilganda ishlaydigan tinglovchi 5 soniya davom etadigan hisob qiladi. Shu 5 soniyada foydalanuvchi boshqa tugmani bossa nima bo'ladi?

Javob

Ikkinchi tugmaning tinglovchisi darhol ishlamaydi. Stekda birinchi tinglovchining konteksti turibdi — u tugamaguncha boshqa kod bajarila olmaydi. Brauzer bosishni eslab qoladi va stek bo'shagach ishlatadi. Foydalanuvchi esa 5 soniya "qotib qolgan" sahifani ko'radi. Shuning uchun tinglovchilar qisqa bo'lishi kerak.

7. Ko'p uchraydigan xatolar

7.1 Funksiya o'zgaruvchisi chaqiruvlar orasida "saqlanadi" deb kutish

js
function tashrifniSana() {
  let soni = 0;
  soni++;
  return soni;
}

tashrifniSana();
tashrifniSana();
console.log(tashrifniSana()); // 1

Uch marta chaqirildi, lekin javob 1. Har chaqiruv yangi kontekst, yangi soni = 0. Tuzatish: chaqiruvlar orasida saqlanishi kerak bo'lgan qiymat funksiyadan tashqarida yashashi kerak — masalan, holat obyektida (Holatdan UI chizish). Funksiya ichida "o'z xotirasi" bo'lgan hisoblagichni esa Closure amaliyotda darsida yasaymiz.

7.2 Bir-birini cheksiz chaqiradigan funksiyalar

js
function stolniTekshir(stol) {
  return bronniTekshir(stol);
}

function bronniTekshir(stol) {
  return stolniTekshir(stol);
}

stolniTekshir(4);
text
RangeError: Maximum call stack size exceeded

Rekursiya bitta funksiyada bo'lishi shart emas. Bu yerda ikki funksiya navbat bilan bir-birini chaqiradi va hech biri tugamaydi. Har chaqiruv stekka yangi kontekst qo'shadi — stek to'lib ketadi (Rekursiya asoslari). Tuzatish: stack trace'da bir xil ikki nom navbatma-navbat takrorlansa — shu ikki funksiyaning qaysi biri to'xtashi kerakligini toping.

7.3 E'lonni chaqiruv deb o'ylash

function hisobla() { ... } yozilishi bilan hech narsa bajarilmaydi va kontekst yaratilmaydi. Funksiya faqat ro'yxatga olinadi. hisobla() — qavslar bilan chaqirilganda — kontekst paydo bo'ladi. Debug paytida "funksiya ishlamayapti" desangiz, avval uni chaqirayotganingizni tekshiring.

8. Mashqlar

1-mashq (oson): Stekni chizing

console.log bajarilayotgan paytda stekda qaysi kontekstlar bor? Pastdan tepaga yozing.

js
function sabziTogra() {
  console.log("Sabzi to'g'ralmoqda");
}

function sabzavotTayyorla() {
  sabziTogra();
}

function oshPishir() {
  sabzavotTayyorla();
}

oshPishir();
Yechim

Pastdan tepaga: global → oshPishir() → sabzavotTayyorla() → sabziTogra(). To'rt kontekst. sabziTogra tepada — u bajarilmoqda, qolgan uchtasi uni kutyapti. Tekshirish uchun console.log o'rniga console.trace() yozing (console API) — Node har kontekstni at qatori bilan chiqaradi.

2-mashq (o'rta): Tartibni oldindan ayting

Kodni ishga tushirmasdan, konsolda nima va qaysi tartibda chiqishini yozing. Keyin tekshiring.

js
function choyQuy() {
  console.log("2. Choy quyildi");
}

function stolgaOlibBor() {
  console.log("1. Patnis olindi");
  choyQuy();
  console.log("3. Stolga qo'yildi");
}

console.log("0. Buyurtma keldi");
stolgaOlibBor();
console.log("4. Tayyor");
Yechim

Konsolda:

text
0. Buyurtma keldi
1. Patnis olindi
2. Choy quyildi
3. Stolga qo'yildi
4. Tayyor

stolgaOlibBor 7-qatorda choyQuy ni chaqirdi va to'xtab turdi. choyQuy konteksti tugagach, stolgaOlibBor aynan to'xtagan joyidan — 8-qatordan — davom etdi. "3" faqat "2" dan keyin chiqadi: stekda tepadagi tugamaguncha, pastdagisi davom etmaydi.

3-mashq (qiyin): Ikki funksiyali rekursiya

juftmi(n) va toqmi(n) funksiyalarini yozing. % ishlatmang — ular bir-birini chaqirsin: juftmi(0) — true, toqmi(0) — false, aks holda juftmi(n) = toqmi(n - 1) va aksincha. Stekning eng katta chuqurligini sanang: global o'zgaruvchi chuqurlik har kontekst boshida bittaga oshsin, tugashidan oldin kamaysin; eng kattasi eng da saqlansin.

Yechim
js
let chuqurlik = 0;
let eng = 0;

function kirdi() {
  chuqurlik++;
  eng = Math.max(eng, chuqurlik);
}

function juftmi(n) {
  kirdi();
  const javob = n === 0 ? true : toqmi(n - 1);
  chuqurlik--;
  return javob;
}

function toqmi(n) {
  kirdi();
  const javob = n === 0 ? false : juftmi(n - 1);
  chuqurlik--;
  return javob;
}

console.log(juftmi(4)); // true
console.log(eng); // 5
console.log(toqmi(3)); // true
console.log(chuqurlik); // 0

juftmi(4) → toqmi(3) → juftmi(2) → toqmi(1) → juftmi(0): stekda bir vaqtda 5 ta kontekst (global'siz). Oxirida chuqurlik yana 0 — har kirgan kontekst chiqib ketdi. kirdi ning o'z konteksti ham bir lahzaga yaratiladi, lekin u darhol tugaydi — biz faqat juftmi/toqmi larni sanadik. juftmi(-1) chaqirsangiz — n hech qachon 0 bo'lmaydi va RangeError: Maximum call stack size exceeded.

4-mashq: Vazifalar qadami — bitta bosishning yo'li

Bu darsda vazifalar kodini o'zgartirmaymiz — uning ichiga qaraymiz. Natijani mashqlar repoga yozasiz: kurs/mashqlar/10/19-call-stack/javoblar.md.

  1. vazifalar ni Live Server'da oching, DevTools → Sources, vazifalar.js.
  2. statistika funksiyasining birinchi qatoriga (const guruhlar = Object.groupBy() breakpoint qo'ying. Sahifani yangilang — u darhol to'xtaydi. Call Stack ni yozing. F8 bilan davom ettiring.
  3. "Non olish" katagini bosing — yana to'xtaydi. Call Stack'ni yozing.
  4. Yangi vazifa qo'shing va «Faol» filtrini bosing — har birida Call Stack'ni yozing.
  5. Savol: to'rt holatda qaysi ikki qator doim bir xil? Bu nimani bildiradi?
Yechim

javoblar.md (Chrome'da, tepadan pastga — DevTools tepadagi kontekstni birinchi ko'rsatadi):

text
Sahifa ochilganda:   statistika ← render ← (anonymous)
Katakni bosganda:    statistika ← render ← vazifaniAlmashtir ← (anonymous)
Vazifa qo'shganda:   statistika ← render ← vazifaQosh ← (anonymous)
Filtrni bosganda:    statistika ← render ← filtrniTanla ← (anonymous)

Eng pastdagi (anonymous): sahifa ochilganda — skriptning o'zi (global kontekst), qolganlarida — nomsiz arrow funksiya, ya'ni hodisa tinglovchisi.

Tepadagi ikkitasi — statistika va render — doim bir xil. Demak ilova holatni qanday o'zgartirmasin, ekran bitta yo'l bilan — render() orqali — yangilanadi. Bu Holatdan UI chizish qolipining isboti: "holatni o'zgartir → render()". Uchinchi qator esa holatni aynan kim o'zgartirganini ko'rsatadi.

Qo'shimcha: katakni bosgandagi Call Stack'da vazifaniAlmashtir qatorini bosing. Scope bo'limida o'sha kontekstning id parametri ko'rinadi — siz bosgan vazifaning raqami. Har stek qavati — o'z o'zgaruvchilari bilan alohida kontekst.

Breakpoint'ni olib tashlang. Commit — mashqlar repoda:

bash
git add 10/19-call-stack/javoblar.md
git commit -m "10/19: vazifalar call stack'ini yoz"

9. Real ishda

  • Debug. Xato loglari (Sentry kabi xizmatlar) foydalanuvchidagi xatoni stack trace bilan yuboradi. Uni kontekstlar ro'yxati sifatida o'qiy olgan dasturchi xatoni ancha tez topadi.
  • Performans. Brauzer DevTools'ining Performance paneli vaqt bo'yicha call stack'ni chizadi ("flame chart"). Qaysi funksiya stekni uzoq band qilganini shu yerda ko'rasiz — sahifa nega qotayotganini topishning asosiy usuli.
  • Intervyu. "Execution context nima?", "Call stack qanday ishlaydi?", "JavaScript nega bir oqimli?" — boshlang'ich (junior) va o'rta (middle) darajali dasturchi intervyularida juda ko'p beriladi. Keyingi savol odatda hoisting va closure haqida bo'ladi — ular ham shu mavzuning davomi.

Xulosa

  • Execution context — bajarilayotgan kod uchun ichki yozuv: o'zgaruvchilar, tashqi havola, this.
  • Global kontekst bitta; funksiya konteksti har chaqiruvda yangisi yaratiladi. E'lon kontekst yaratmaydi.
  • Har kontekst ikki bosqichdan o'tadi: yaratish (e'lonlar ro'yxatga) va bajarish (qatorma-qator).
  • Call stack — kontekstlar taxlami: chaqiruv — tepaga qo'yish, return — olib tashlash.
  • Stack trace — xato paytidagi stek surati; at qatorlari — kontekstlar, pastdan tepaga o'sgan.
  • Stek bitta — bir vaqtda bitta ish bajariladi.

Keyingi dars: Leksik scope va scope zanjiri — kontekstning ikkinchi qismi, "tashqi havola"ni ochamiz: topilmagan nom qayerdan va qaysi tartibda qidiriladi.

Manbalar

  • ECMAScript 2025 Language Specification: "Execution Contexts", "Execution Context Stack" — tc39.es/ecma262
  • MDN: "Call stack" (Glossary), "JavaScript execution model" — developer.mozilla.org
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript execution context va call stack: kod ichidan qanday bajariladi — IlmHamroh