Mundarija (30)
- Bu darsda
- 1. Nega bu kerak?
- 2. Scope nima?
- 3. Global scope
- 3.1 Global o'zgaruvchining xavfi
- 4. Funksiya scope
- 4.1 Har chaqiruvda — yangi o'zgaruvchilar
- 4.2 Turli funksiyalarda bir xil nom — muammo emas
- 5. Blok scope
- 5.1 for siklidagi i
- 5.2 var bloklarni "ko'rmaydi"
- 6. Ichma-ich scope'lar: kim kimni ko'radi?
- 6.1 Funksiya ichidagi funksiya
- 7. Tashqi o'zgaruvchini o'zgartirish
- 8. Shadowing: ichkaridagi nom tashqaridagini "yopadi"
- 8.1 Parametr ham soyalaydi
- 8.2 Shadowing qachon xato keltirib chiqaradi?
- 9. Eng tor scope qoidasi
- 10. Ko'p uchraydigan xatolar
- 10.1 Funksiya ichidagi o'zgaruvchini tashqarida ishlatish
- 10.2 Blok ichida e'lon qilib, tashqarida ishlatish
- 10.3 let ni unutish
- 10.4 Shadowing va "e'londan oldin" murojaat
- 10.5 Bitta scope'da bir nomni ikki marta e'lon qilish
- 11. Mashqlar
- 1-mashq (oson): Xatoni tuzating
- 2-mashq (o'rta): Natijani oldindan ayting
- 3-mashq (qiyin): Taksi hisoblagichi
- 12. Real ishda
- Xulosa
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 ichidagilet/constesa 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 definedxatosini 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:
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:
ReferenceError: chegirma is not definedchegirma 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.
const choyxonaNomi = "Bahor";
function salomBer() {
console.log(`${choyxonaNomi} choyxonasiga xush kelibsiz!`);
}
function xayrlash() {
console.log(`${choyxonaNomi} sizni yana kutadi!`);
}
salomBer();
xayrlash();Konsolda:
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:
let jami = 0;
function choyQosh() {
jami = jami + 3000;
}
function hisobniTozala() {
jami = 0;
}
choyQosh();
choyQosh();
hisobniTozala();
console.log(jami); // 0Ikki 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.
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); // undefinedtypeof 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.
function mehmonSana() {
let soni = 0;
soni = soni + 1;
console.log(`Mehmonlar: ${soni}`);
}
mehmonSana();
mehmonSana();
mehmonSana();Konsolda:
Mehmonlar: 1
Mehmonlar: 1
Mehmonlar: 1Uch 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.
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)); // 16000Ikkala 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?
jsfunction 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).
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:
ReferenceError: chegirma is not definedchegirma 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:
for (let i = 1; i <= 3; i++) {
console.log(`${i}-mijoz`);
}
console.log(typeof i);Konsolda:
1-mijoz
2-mijoz
3-mijoz
undefinedSikldan 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:
if (true) {
var eski = "var bilan";
let yangi = "let bilan";
}
console.log(eski); // var bilan
console.log(typeof yangi); // undefinedvar 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 keyinconsole.log(i)yozsak nima bo'ladi?leto'rnigavarbo'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.
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:
osh: Toshkent, Chilonzor, 30 daqiqaif 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:
function chekChiqar(mijoz) {
const choyxona = "Bahor";
function sarlavhaChiqar() {
console.log(`${choyxona} | Mijoz: ${mijoz}`);
}
sarlavhaChiqar();
console.log("Choy — 3000 so'm");
}
chekChiqar("Malika");Konsolda:
Bahor | Mijoz: Malika
Choy — 3000 so'msarlavhaChiqar 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:
let buyurtmalar = 0;
function yangiBuyurtma() {
buyurtmalar = buyurtmalar + 1;
}
yangiBuyurtma();
yangiBuyurtma();
console.log(buyurtmalar); // 2E'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?
const shahar = "Toshkent";
function safargaChiq() {
const shahar = "Samarqand";
console.log(`Ichkarida: ${shahar}`);
}
safargaChiq();
console.log(`Tashqarida: ${shahar}`);Konsolda:
Ichkarida: Samarqand
Tashqarida: ToshkentBu 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:
const narx = 5000;
function chegirmali(narx) {
return narx - 1000;
}
console.log(chegirmali(20000)); // 19000
console.log(narx); // 5000Funksiya 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:
let holat = "yopiq";
function dokonniOch() {
let holat = "ochiq";
console.log(`Ichkarida: ${holat}`);
}
dokonniOch();
console.log(`Tashqarida: ${holat}`);Konsolda:
Ichkarida: ochiq
Tashqarida: yopiqDo'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?
jslet 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:
let km = 0;
let narx = 0;
function taksi(masofa) {
km = masofa;
narx = 7000 + km * 2500;
return narx;
}
console.log(taksi(4)); // 17000Yaxshi — o'zgaruvchilar kerakli joyda:
function taksi(km) {
const narx = 7000 + km * 2500;
return narx;
}
console.log(taksi(4)); // 17000Natija bir xil, lekin ikkinchi variant ancha xavfsiz:
- Boshqa funksiya
narxni tasodifan buzib qo'ya olmaydi. narxqayerda 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
function oylikSoligi(summa) {
const soliq = summa * 0.12;
}
oylikSoligi(5000000);
console.log(soliq);ReferenceError: soliq is not definedTarjimasi: "soliq aniqlanmagan". soliq funksiya scope'ida qolib ketdi. Yechim: qiymatni return bilan qaytaring va natijani o'zgaruvchiga saqlang:
function oylikSoligi(summa) {
const soliq = summa * 0.12;
return soliq;
}
const soliq = oylikSoligi(5000000);
console.log(soliq); // 600000Tashqi 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:
const summa = 120000;
let chegirma = 0;
if (summa > 100000) {
chegirma = 10000;
}
console.log(summa - chegirma); // 11000010.3 let ni unutish
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:
ReferenceError: jami is not definedYechim: 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
let narx = 10000;
function yangila() {
console.log(narx);
let narx = 12000;
}
yangila();ReferenceError: Cannot access 'narx' before initializationTarjimasi: "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
let mijoz = "Ali";
let mijoz = "Vali";SyntaxError: Identifier 'mijoz' has already been declaredBitta 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.
function yetkazishNarxi(km) {
const narx = km * 3000;
}
yetkazishNarxi(5);
console.log(`Yetkazish: ${narx} so'm`);Yechim
function yetkazishNarxi(km) {
const narx = km * 3000;
return narx;
}
const narx = yetkazishNarxi(5);
console.log(`Yetkazish: ${narx} so'm`); // Yetkazish: 15000 so'mnarx 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.
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:
1: Jasur
2: Malika
3: AliUch 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:
function buyurtmaQabul(manzil) {
let soni = 0;
soni = soni + 1;
console.log(`${soni}-buyurtma: ${manzil}`);
}
buyurtmaQabul("Chilonzor");
buyurtmaQabul("Yunusobod");- Nega doim
1chiqishini tushuntiring. - Kodni tuzating:
1-buyurtma: Chilonzor,2-buyurtma: Yunusobodchiqsin.
Yechim
sonifunksiya scope'ida. Har chaqiruvda funksiya noldan boshlanadi:let soni = 0qaytadan ishlaydi. Oldingi chaqiruvningsonisi allaqachon yo'q.Hisoblagich chaqiruvlar orasida "yashashi" kerak. Demak, u funksiyadan tashqarida e'lon qilinadi:
let soni = 0;
function buyurtmaQabul(manzil) {
soni = soni + 1;
console.log(`${soni}-buyurtma: ${manzil}`);
}
buyurtmaQabul("Chilonzor");
buyurtmaQabul("Yunusobod");Konsolda:
1-buyurtma: Chilonzor
2-buyurtma: YunusobodE'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
mehmonSanamisolidagidek. Shuning uchun React'da holatni saqlash uchun maxsus vositalar bor. - ESLint: loyihalarda
no-undef(e'lon qilinmagan nom),no-shadow(tasodifiy soyalash) vano-varqoidalari yoqilgan bo'ladi. Ular aynan shu darsdagi xatolarni avtomatik topadi. - Intervyu: "
var,letvaconstning 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
letxavfli, uni kam ishlating. - Funksiya ichidagi o'zgaruvchi va parametrlar faqat shu funksiyada yashaydi va har chaqiruvda qaytadan yaratiladi.
let/const— blok scope:if,forva{ }dan tashqariga chiqmaydi.varbloklarni 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
constbilan e'lon qiling.
Keyingi dars: Funksiya — qiymat: callback va HOF — funksiyani boshqa funksiyaga argument qilib berish va funksiyadan funksiya qaytarishni o'rganamiz.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!