IlmHamroh
JavaScript Full-stack/8-qism. JavaScript asoslari42/61-dars16 daqiqa
Mundarija (30)

JavaScript scope: global, funksiya va blok ko'rinish doirasi

Qisqacha: Scope (ko'rinish doirasi) — o'zgaruvchi ko'rinadigan kod qismi. Funksiya ichida e'lon qilingan o'zgaruvchi faqat shu funksiyada, { } blok ichidagi let/const esa faqat shu blokda ko'rinadi. Ichkaridagi kod tashqaridagini ko'radi, tashqaridagi kod ichkarini ko'rmaydi.

Bu darsda

  • Scope nima ekanini va u qaysi muammoni hal qilishini tushunasiz.
  • Global, funksiya va blok scope'ni farqlay olasiz.
  • Kodga qarab qaysi o'zgaruvchi qayerda ko'rinishini ayta olasiz.
  • Shadowing (bir xil nomli o'zgaruvchi) qanday ishlashini tushuntira olasiz.
  • ReferenceError: ... is not defined xatosini tez topib tuzata olasiz.

Oldin bilishingiz kerak: var va nega undan voz kechildi, return va erta qaytish, Function expression va arrow funksiyalar.

1. Nega bu kerak?

O'tgan darslarda funksiyalarni har xil shaklda yozishni o'rgandik. Funksiya ichida o'zgaruvchilar ham e'lon qildik. Lekin bir savol ochiq qoldi: funksiya ichidagi o'zgaruvchini tashqarida ishlatsa bo'ladimi?

Tasavvur qiling: Jasur taksi ilovasi yozyapti. Unda 50 ta funksiya bor va deyarli hammasida narx degan o'zgaruvchi ishlatiladi. Agar hamma o'zgaruvchi hamma joydan ko'rinsa nima bo'ladi? Bir funksiya narx ni o'zgartiradi — boshqa funksiyadagi hisob buziladi. Xatoni topish uchun 50 ta funksiyani ko'rib chiqish kerak bo'ladi.

JavaScript bu muammoni scope bilan hal qiladi. Har funksiya va har blok o'zining "shaxsiy xonasi"ga ega. U yerdagi o'zgaruvchilar tashqariga chiqmaydi.

Hayotdan o'xshatish: tonirovka qilingan mashina. Ichida o'tirgan odam ko'chani bemalol ko'radi. Ko'chadagi odam esa mashina ichini ko'rmaydi. Scope ham xuddi shunday — ichkaridan tashqari ko'rinadi, tashqaridan ichkari ko'rinmaydi.

2. Scope nima?

Avval misol ko'raylik:

js
function chegirmaHisobla() {
  const chegirma = 5000;
  console.log(`Chegirma: ${chegirma} so'm`);
}

chegirmaHisobla();
console.log(chegirma);

Konsolda avval Chegirma: 5000 so'm chiqadi, keyin qizil xato:

text
ReferenceError: chegirma is not defined

chegirma funksiya ichida e'lon qilingan. Funksiya ichida u bemalol ishlaydi. Tashqarida esa JavaScript uni "tanimaydi".

Ko'rinish doirasi (scope) — o'zgaruvchi ko'rinadigan va ishlatilishi mumkin bo'lgan kod qismi. Har bir o'zgaruvchi o'z scope'ida "yashaydi". Undan tashqarida bu nom mavjud emas.

JavaScript'da scope'ning uchta asosiy turi bor:

Tur Qayerda paydo bo'ladi Kim ko'radi
Global scope Hech qanday funksiya yoki blok ichida emas Butun fayl
Funksiya scope Funksiya tanasi { } ichida Faqat shu funksiya
Blok scope if, for, while yoki oddiy { } ichida Faqat shu blok

3. Global scope

Fayl eng tashqi qismida — hech qanday funksiya yoki { } ichida bo'lmagan joyda — e'lon qilingan o'zgaruvchi global bo'ladi. U fayldagi hamma joydan ko'rinadi, funksiyalar ichidan ham.

js
const choyxonaNomi = "Bahor";

function salomBer() {
  console.log(`${choyxonaNomi} choyxonasiga xush kelibsiz!`);
}

function xayrlash() {
  console.log(`${choyxonaNomi} sizni yana kutadi!`);
}

salomBer();
xayrlash();

Konsolda:

text
Bahor choyxonasiga xush kelibsiz!
Bahor sizni yana kutadi!

choyxonaNomi ikkala funksiyadan ham ko'rinadi. Chunki u global scope'da — "ko'chada" turibdi, hamma uni ko'radi.

3.1 Global o'zgaruvchining xavfi

Global o'zgaruvchi qulay tuyuladi: hamma joydan ishlataverasiz. Lekin let bilan e'lon qilingan global o'zgaruvchini istalgan funksiya o'zgartira oladi:

js
let jami = 0;

function choyQosh() {
  jami = jami + 3000;
}

function hisobniTozala() {
  jami = 0;
}

choyQosh();
choyQosh();
hisobniTozala();
console.log(jami); // 0

Ikki choy qo'shdik, lekin natija 0. Kichik faylda sababini tez topasiz. 2000 qatorli faylda esa "jami ni kim nolga tushirdi?" savoli soatlab vaqt oladi.

Shuning uchun dasturchilar global o'zgaruvchini imkon qadar kam ishlatadi. Ko'pincha global darajada faqat const bilan o'zgarmas qiymatlar qoladi: choyxona nomi, soliq foizi, valyuta nomi.

Tekshirib ko'ring: Global o'zgaruvchi funksiya ichidan ko'rinadimi?

Javob

Ha, ko'rinadi. Global scope — eng tashqi "ko'cha". Ichkaridagi har bir funksiya undan o'qiy oladi (va let bo'lsa, o'zgartira ham oladi). Aynan shuning uchun global let xavfli — uni istalgan joy o'zgartirib qo'yishi mumkin.

4. Funksiya scope

Funksiya ichida e'lon qilingan o'zgaruvchi faqat shu funksiya ichida ko'rinadi. Bu funksiya scope (function scope) deyiladi.

Parametrlar ham funksiya scope'iga tegishli. Ular funksiya ichida oddiy o'zgaruvchi kabi ishlaydi, tashqarida esa yo'q.

js
function taksiNarxi(km) {
  const boshlangich = 7000;
  const kmNarxi = 2500;
  return boshlangich + km * kmNarxi;
}

console.log(taksiNarxi(4)); // 17000
console.log(typeof km); // undefined
console.log(typeof boshlangich); // undefined

typeof noma'lum nom uchun xato bermaydi, "undefined" qaytaradi. Shu bilan tekshirdik: km ham, boshlangich ham funksiyadan tashqarida mavjud emas.

4.1 Har chaqiruvda — yangi o'zgaruvchilar

Funksiya chaqirilganda uning o'zgaruvchilari "tug'iladi". Funksiya ishini tugatganda ular yo'qoladi. Keyingi chaqiruvda hammasi boshidan yaratiladi.

js
function mehmonSana() {
  let soni = 0;
  soni = soni + 1;
  console.log(`Mehmonlar: ${soni}`);
}

mehmonSana();
mehmonSana();
mehmonSana();

Konsolda:

text
Mehmonlar: 1
Mehmonlar: 1
Mehmonlar: 1

Uch marta chaqirdik, lekin har safar 1. Chunki har chaqiruvda let soni = 0 qaytadan ishlaydi. Oldingi chaqiruvdagi soni allaqachon yo'q bo'lib ketgan.

Boshida bu g'alati tuyulishi tabiiy. Buni doskaga o'xshating: har darsdan keyin doska tozalanadi. Keyingi dars toza doskadan boshlanadi.

"Unda mehmonlarni qanday sanaymiz?" degan savol tug'ilishi tabiiy. Qiymat chaqiruvlar orasida saqlanishi kerak bo'lsa, o'zgaruvchi funksiyadan tashqarida e'lon qilinadi. Buni shu darsning "Tashqi o'zgaruvchini o'zgartirish" bo'limida ko'ramiz.

4.2 Turli funksiyalarda bir xil nom — muammo emas

Scope'ning eng katta foydasi shu: har funksiya o'z nomlarini bemalol tanlaydi.

js
function choyNarxi(soni) {
  const narx = soni * 3000;
  return narx;
}

function somsaNarxi(soni) {
  const narx = soni * 8000;
  return narx;
}

console.log(choyNarxi(2)); // 6000
console.log(somsaNarxi(2)); // 16000

Ikkala funksiyada ham soni va narx bor. Lekin ular bir-biriga halal bermaydi. Xuddi ikki xonadonda Ali ismli bola bo'lgandek — har biri o'z uyida, chalkashlik yo'q.

Tekshirib ko'ring: Quyidagi kod nima chiqaradi?

js
function hisobla() {
  const natija = 10 * 5;
}
hisobla();
console.log(natija);
Javob

ReferenceError: natija is not defined. natija funksiya scope'ida yashaydi va funksiya tugashi bilan yo'qoladi. Qiymatni tashqariga olib chiqish uchun return natija; yozib, chaqiruv natijasini o'zgaruvchiga saqlash kerak: const n = hisobla();.

5. Blok scope

Blok (block) — jingalak qavslar { } ichidagi kod. if, else, for, while tanalari — hammasi blok. let va const bilan e'lon qilingan o'zgaruvchi faqat o'z bloki ichida ko'rinadi. Bu blok scope (block scope).

js
const summa = 120000;

if (summa > 100000) {
  const chegirma = 10000;
  console.log(`Chegirma bor: ${chegirma} so'm`);
}

console.log(chegirma);

Konsolda avval Chegirma bor: 10000 so'm, keyin:

text
ReferenceError: chegirma is not defined

chegirma if bloki ichida tug'ildi va blok tugashi bilan yo'qoldi.

5.1 for siklidagi i

for (let i = ...) dagi i ham blok scope'ga ega. U faqat sikl ichida yashaydi:

js
for (let i = 1; i <= 3; i++) {
  console.log(`${i}-mijoz`);
}

console.log(typeof i);

Konsolda:

text
1-mijoz
2-mijoz
3-mijoz
undefined

Sikldan keyin i yo'q. Keyingi siklda yana i nomini bemalol ishlatasiz.

5.2 var bloklarni "ko'rmaydi"

var darsida aytgan edik: var blok scope'ga bo'ysunmaydi. U faqat funksiya scope'ini taniydi:

js
if (true) {
  var eski = "var bilan";
  let yangi = "let bilan";
}

console.log(eski); // var bilan
console.log(typeof yangi); // undefined

var bilan e'lon qilingan eski blokdan "sizib" chiqdi. let bilan e'lon qilingan yangi esa blok ichida qoldi. Aynan shu sababli zamonaviy kodda faqat let va const ishlatiladi.

Tekshirib ko'ring: for (let i = 0; i < 3; i++) { } siklidan keyin console.log(i) yozsak nima bo'ladi? let o'rniga var bo'lsa-chi?

Javob

let bilan — ReferenceError: i is not defined, chunki i faqat sikl blokida yashaydi. var bilan — 3 chiqadi. var blokni tanimaydi va sikldan keyin ham yashaydi; oxirgi qiymati 3 (shu qiymatda shart false bo'lib, sikl to'xtagan).

6. Ichma-ich scope'lar: kim kimni ko'radi?

Scope'lar bir-birining ichiga joylashadi. Blok funksiya ichida, funksiya global scope ichida bo'ladi. Qoida bitta: ichkaridagi kod tashqaridagi hamma narsani ko'radi, tashqaridagi kod ichkarini ko'rmaydi.

js
const shahar = "Toshkent";

function buyurtmaBer(taom) {
  const manzil = "Chilonzor";

  if (taom === "osh") {
    const vaqt = "30 daqiqa";
    console.log(`${taom}: ${shahar}, ${manzil}, ${vaqt}`);
  }
}

buyurtmaBer("osh");

Konsolda:

text
osh: Toshkent, Chilonzor, 30 daqiqa

if bloki ichidagi console.log to'rtala nomni ham ko'radi:

Nom Qayerda e'lon qilingan if ichidan ko'rinadimi?
vaqt if bloki Ha — o'z bloki
taom Funksiya parametri Ha — tashqi funksiya
manzil Funksiya tanasi Ha — tashqi funksiya
shahar Global Ha — eng tashqi

JavaScript nomni qidirganda avval o'z blokiga qaraydi. Topmasa — bir qavat tashqariga chiqadi, keyin yana tashqariga. Global scope'gacha topolmasa — ReferenceError. Bu qidiruv yo'li scope zanjiri deyiladi, uni Leksik scope va scope zanjiri darsida chuqur o'rganamiz.

6.1 Funksiya ichidagi funksiya

Funksiya ichida boshqa funksiya e'lon qilsa ham bo'ladi. Ichki funksiya tashqi funksiyaning o'zgaruvchilarini ko'radi:

js
function chekChiqar(mijoz) {
  const choyxona = "Bahor";

  function sarlavhaChiqar() {
    console.log(`${choyxona} | Mijoz: ${mijoz}`);
  }

  sarlavhaChiqar();
  console.log("Choy — 3000 so'm");
}

chekChiqar("Malika");

Konsolda:

text
Bahor | Mijoz: Malika
Choy — 3000 so'm

sarlavhaChiqar o'zi hech narsa e'lon qilmagan. Lekin u tashqi funksiyadagi choyxona va mijoz ni bemalol ishlatdi.

Tekshirib ko'ring: Yuqoridagi kod oxiriga sarlavhaChiqar(); qatorini qo'shsak nima bo'ladi?

Javob

ReferenceError: sarlavhaChiqar is not defined. sarlavhaChiqar — chekChiqar ichida e'lon qilingan, ya'ni uning funksiya scope'ida yashaydi. Global kod ichkarini ko'rmaydi (tonirovkali mashinadagi kabi).

7. Tashqi o'zgaruvchini o'zgartirish

Ichki kod tashqi let o'zgaruvchini faqat o'qibgina qolmay, o'zgartira ham oladi:

js
let buyurtmalar = 0;

function yangiBuyurtma() {
  buyurtmalar = buyurtmalar + 1;
}

yangiBuyurtma();
yangiBuyurtma();
console.log(buyurtmalar); // 2

E'tibor bering: funksiya ichida let yo'q. Biz yangi o'zgaruvchi yaratmadik — tashqaridagi buyurtmalar ni yangiladik.

Yuqoridagi mehmonSana muammosining yechimi ham shu. Hisoblagich har chaqiruvda nolga tushmasligi uchun u funksiyadan tashqarida yashashi kerak.

Diqqat: Funksiya tashqaridagi narsani o'zgartirishi — "yon ta'sir" (side effect) deyiladi. Ba'zan u kerak, lekin ko'p bo'lsa kod chalkashadi. Bu haqda Pure funksiya va side effect darsida batafsil gaplashamiz.

8. Shadowing: ichkaridagi nom tashqaridagini "yopadi"

Ichki scope'da tashqaridagi nom bilan yangi o'zgaruvchi e'lon qilsangiz nima bo'ladi?

js
const shahar = "Toshkent";

function safargaChiq() {
  const shahar = "Samarqand";
  console.log(`Ichkarida: ${shahar}`);
}

safargaChiq();
console.log(`Tashqarida: ${shahar}`);

Konsolda:

text
Ichkarida: Samarqand
Tashqarida: Toshkent

Bu soyalash (shadowing) deyiladi: ichki o'zgaruvchi tashqi o'zgaruvchini "soya" qilib yopadi. Funksiya ichida shahar deganda JavaScript birinchi bo'lib ichkaridagisini topadi va qidiruvni to'xtatadi. Tashqi shahar esa o'zgarmay qoladi.

Hayotdan misol: sinfda ikkita Ali bor — biri sizning partadoshingiz. Partada "Ali" desangiz, avval yoningizdagi Ali qaraydi. Uzoqdagi Ali eshitmaydi ham.

8.1 Parametr ham soyalaydi

Parametr nomi tashqi o'zgaruvchi bilan bir xil bo'lsa, u ham soyalaydi:

js
const narx = 5000;

function chegirmali(narx) {
  return narx - 1000;
}

console.log(chegirmali(20000)); // 19000
console.log(narx); // 5000

Funksiya ichidagi narx — parametr (20000). Global narx (5000) ga tegilmadi.

8.2 Shadowing qachon xato keltirib chiqaradi?

Ko'pincha shadowing tasodifan bo'ladi. Dasturchi tashqi o'zgaruvchini yangilamoqchi bo'ladi, lekin odatdan let yozib yuboradi:

js
let holat = "yopiq";

function dokonniOch() {
  let holat = "ochiq";
  console.log(`Ichkarida: ${holat}`);
}

dokonniOch();
console.log(`Tashqarida: ${holat}`);

Konsolda:

text
Ichkarida: ochiq
Tashqarida: yopiq

Do'kon ochilmadi! let holat yangi o'zgaruvchi yaratdi, tashqi holat esa "yopiq" bo'lib qoldi. Yechim — ichkaridagi let ni olib tashlash: holat = "ochiq";.

Maslahat: Chalkashmaslik uchun ichki va tashqi o'zgaruvchilarga iloji boricha turli nom bering. Real loyihalarda ESLint degan vosita tasodifiy shadowing'ni topib ogohlantiradi.

Tekshirib ko'ring: Konsolda nima chiqadi?

js
let ball = 10;
function oyin() {
  let ball = 50;
  ball = ball + 5;
}
oyin();
console.log(ball);
Javob

10. Funksiya ichida let ball — yangi, ichki o'zgaruvchi. ball + 5 amali aynan shu ichki ball bilan bajarildi (55) va funksiya tugashi bilan yo'qoldi. Global ball ga hech kim tegmadi.

9. Eng tor scope qoidasi

Endi amaliy qoida: o'zgaruvchini u kerak bo'lgan eng tor joyda e'lon qiling. Faqat bitta funksiyaga kerakmi — shu funksiya ichida. Faqat if ichida kerakmi — shu blok ichida.

Yomon — hamma narsa global:

js
let km = 0;
let narx = 0;

function taksi(masofa) {
  km = masofa;
  narx = 7000 + km * 2500;
  return narx;
}

console.log(taksi(4)); // 17000

Yaxshi — o'zgaruvchilar kerakli joyda:

js
function taksi(km) {
  const narx = 7000 + km * 2500;
  return narx;
}

console.log(taksi(4)); // 17000

Natija bir xil, lekin ikkinchi variant ancha xavfsiz:

  • Boshqa funksiya narx ni tasodifan buzib qo'ya olmaydi.
  • narx qayerda ishlatilishini qidirish shart emas — hammasi ko'z oldida.
  • Funksiya tugagach, o'zgaruvchilar xotirani bo'shatadi.

Qo'shimcha qoida: iloji bo'lsa const ishlating, qiymat o'zgarishi kerak bo'lsagina let. Tor scope + const — xatoga kam joy qoldiradi.

Bo'sh joyni to'ldiring. for siklidagi hisoblagich faqat sikl ichida kerak bo'lsa, uni qaysi kalit so'z bilan e'lon qilamiz: for ( i = 0; i < 5; i++).

10. Ko'p uchraydigan xatolar

10.1 Funksiya ichidagi o'zgaruvchini tashqarida ishlatish

js
function oylikSoligi(summa) {
  const soliq = summa * 0.12;
}

oylikSoligi(5000000);
console.log(soliq);
text
ReferenceError: soliq is not defined

Tarjimasi: "soliq aniqlanmagan". soliq funksiya scope'ida qolib ketdi. Yechim: qiymatni return bilan qaytaring va natijani o'zgaruvchiga saqlang:

js
function oylikSoligi(summa) {
  const soliq = summa * 0.12;
  return soliq;
}

const soliq = oylikSoligi(5000000);
console.log(soliq); // 600000

Tashqi soliq va ichki soliq — ikki xil o'zgaruvchi. Ular bir-biriga xalaqit bermaydi.

10.2 Blok ichida e'lon qilib, tashqarida ishlatish

Yuqoridagi chegirma misolini eslang. To'g'ri yo'li — o'zgaruvchini blokdan oldin let bilan e'lon qilish, blok ichida esa faqat qiymat berish:

js
const summa = 120000;
let chegirma = 0;

if (summa > 100000) {
  chegirma = 10000;
}

console.log(summa - chegirma); // 110000

10.3 let ni unutish

js
function hisobla() {
  jami = 25000; // let ham, const ham yo'q
}

hisobla();
console.log(jami);

Bu kodning natijasi fayl qanday ishga tushirilishiga bog'liq. Oddiy skriptda JavaScript xato bermaydi — jimgina global jami yaratadi va 25000 chiqaradi. Bu juda xavfli: siz bilmagan holda global o'zgaruvchi paydo bo'ladi.

Zamonaviy modul fayllarida va "strict mode" da esa shu kod xato beradi:

text
ReferenceError: jami is not defined

Yechim: har bir yangi o'zgaruvchini const yoki let bilan e'lon qiling. Strict mode haqida alohida darsda gaplashamiz.

10.4 Shadowing va "e'londan oldin" murojaat

js
let narx = 10000;

function yangila() {
  console.log(narx);
  let narx = 12000;
}

yangila();
text
ReferenceError: Cannot access 'narx' before initialization

Tarjimasi: "narx ga u tayyor bo'lishidan oldin murojaat qilib bo'lmaydi". Ko'pchilik birinchi qatorda tashqi narx (10000) chiqadi deb o'ylaydi. Lekin JavaScript funksiya ichida let narx borligini oldindan biladi. Shuning uchun butun funksiya bo'ylab narx — ichki o'zgaruvchi, u esa hali tayyor emas. Ya'ni ichki narx tashqisini boshidanoq soyalab qo'yadi, lekin o'zi let qatoriga yetmaguncha o'qishga ruxsat bermaydi. Natijada console.log na tashqi, na ichki narx ni ololmaydi.

Yechim: ichki o'zgaruvchiga boshqa nom bering (yangiNarx) yoki uni ishlatishdan oldin e'lon qiling. Bu hodisaning nomi — Temporal Dead Zone, uni TDZ darsida chuqur ko'ramiz.

10.5 Bitta scope'da bir nomni ikki marta e'lon qilish

js
let mijoz = "Ali";
let mijoz = "Vali";
text
SyntaxError: Identifier 'mijoz' has already been declared

Bitta scope'da bitta nom — bitta let. Qiymatni o'zgartirish uchun ikkinchi marta let yozmang: mijoz = "Vali";. Ichki blokda esa shu nomni qayta e'lon qilish mumkin — bu shadowing bo'ladi.

11. Mashqlar

1-mashq (oson): Xatoni tuzating

Quyidagi kod ReferenceError beradi. Uni shunday tuzatingki, konsolda Yetkazish: 15000 so'm chiqsin.

js
function yetkazishNarxi(km) {
  const narx = km * 3000;
}

yetkazishNarxi(5);
console.log(`Yetkazish: ${narx} so'm`);
Yechim
js
function yetkazishNarxi(km) {
  const narx = km * 3000;
  return narx;
}

const narx = yetkazishNarxi(5);
console.log(`Yetkazish: ${narx} so'm`); // Yetkazish: 15000 so'm

narx funksiya ichida yashaydi, shuning uchun uni return bilan tashqariga "olib chiqdik". Tashqarida chaqiruv natijasini yangi o'zgaruvchiga saqladik.

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

Kodni ishga tushirmasdan, konsolda nima chiqishini qog'ozga yozing. Keyin tekshiring.

js
const ism = "Ali";

function tanishtir() {
  const ism = "Malika";

  if (true) {
    const ism = "Jasur";
    console.log(`1: ${ism}`);
  }

  console.log(`2: ${ism}`);
}

tanishtir();
console.log(`3: ${ism}`);
Yechim

Konsolda:

text
1: Jasur
2: Malika
3: Ali

Uch xil ism bor, har biri o'z scope'ida. if ichida eng yaqini — Jasur. if dan chiqqach, blok o'zgaruvchisi yo'qoladi va funksiyaniki — Malika ko'rinadi. Funksiyadan tashqarida faqat global Ali qoladi. Uchalasi ham shadowing: ichkaridagi nom tashqaridagini yopadi, lekin uni o'zgartirmaydi.

3-mashq (qiyin): Taksi hisoblagichi

Jasur har bir buyurtmani sanaydigan funksiya yozdi, lekin u doim 1-buyurtma chiqaradi:

js
function buyurtmaQabul(manzil) {
  let soni = 0;
  soni = soni + 1;
  console.log(`${soni}-buyurtma: ${manzil}`);
}

buyurtmaQabul("Chilonzor");
buyurtmaQabul("Yunusobod");
  1. Nega doim 1 chiqishini tushuntiring.
  2. Kodni tuzating: 1-buyurtma: Chilonzor, 2-buyurtma: Yunusobod chiqsin.
Yechim
  1. soni funksiya scope'ida. Har chaqiruvda funksiya noldan boshlanadi: let soni = 0 qaytadan ishlaydi. Oldingi chaqiruvning soni si allaqachon yo'q.

  2. Hisoblagich chaqiruvlar orasida "yashashi" kerak. Demak, u funksiyadan tashqarida e'lon qilinadi:

js
let soni = 0;

function buyurtmaQabul(manzil) {
  soni = soni + 1;
  console.log(`${soni}-buyurtma: ${manzil}`);
}

buyurtmaQabul("Chilonzor");
buyurtmaQabul("Yunusobod");

Konsolda:

text
1-buyurtma: Chilonzor
2-buyurtma: Yunusobod

E'tibor bering: funksiya ichida let yozmadik — tashqi soni ni yangilaymiz.

Bu yechim ishlaydi, lekin soni global bo'lib qoldi — uni istalgan funksiya buzishi mumkin. Hisoblagichni "yashirin" saqlashning chiroyli usuli bor. Uni Closure darsida o'rganamiz.

12. Real ishda

Scope har kuni, har bir faylda ishlaydi:

  • Modullar: real loyihada har bir fayl — alohida modul, uning o'z scope'i bor. Bu haqda Modul semantikasi darsida gaplashamiz.
  • React: komponent ichidagi o'zgaruvchilar har chizishda (render) qaytadan yaratiladi — xuddi mehmonSana misolidagidek. Shuning uchun React'da holatni saqlash uchun maxsus vositalar bor.
  • ESLint: loyihalarda no-undef (e'lon qilinmagan nom), no-shadow (tasodifiy soyalash) va no-var qoidalari yoqilgan bo'ladi. Ular aynan shu darsdagi xatolarni avtomatik topadi.
  • Intervyu: "var, let va const ning farqi nima?" — boshlovchilarga eng ko'p beriladigan savol. To'liq javobda scope albatta tilga olinadi: var — funksiya scope, let/const — blok scope.

Xulosa

  • Scope — o'zgaruvchi ko'rinadigan kod qismi.
  • Global o'zgaruvchi hamma joydan ko'rinadi; global let xavfli, uni kam ishlating.
  • Funksiya ichidagi o'zgaruvchi va parametrlar faqat shu funksiyada yashaydi va har chaqiruvda qaytadan yaratiladi.
  • let/const — blok scope: if, for va { } dan tashqariga chiqmaydi. var bloklarni tanimaydi.
  • Ichkaridan tashqari ko'rinadi, tashqaridan ichkari ko'rinmaydi. Bir xil nom ichkarida e'lon qilinsa — shadowing.
  • O'zgaruvchini kerak bo'lgan eng tor joyda, iloji bo'lsa const bilan e'lon qiling.

Keyingi dars: Funksiya — qiymat: callback va HOF — funksiyani boshqa funksiyaga argument qilib berish va funksiyadan funksiya qaytarishni o'rganamiz.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript scope: global, funksiya va blok ko'rinish doirasi — IlmHamroh