Scope — global, function, block scope
Muammodan boshlaylik
function hisoblash() {
let natija = 42;
}
console.log(natija); // ReferenceError: natija is not defined
Nima uchun? natija funksiya ichida e'lon qilindi — tashqaridan ko'rinmaydi. Bu — scope.
Scope tushunmasdan yozilgan kodda o'zgaruvchilar bir-birini "bosib ketadi", kutilmagan qiymatlar chiqadi, xatolarni topish qiyinlashadi.
Scope nima?
Scope — o'zgaruvchi "ko'rinadigan" hudud. O'zgaruvchi qayerda e'lon qilingan bo'lsa — faqat shu hududda va uning ichida ko'rinadi.
Hayotiy o'xshatma: uy va xonalar. Uyning umumiy zali — hamma ko'radi. Yotoqxonadagi narsa — faqat yotoqxonada ko'rinadi. Mehmonxonadan yotoqxonadagi narsani ko'rib bo'lmaydi.
Global Scope
Funksiya yoki blok tashqarisida e'lon qilingan o'zgaruvchi — global. Hamma joydan ko'rinadi.
const dasturNomi = "DevDocs"; // ← global
function ko_rsat() {
console.log(dasturNomi); // ✅ ko'rinadi
}
ko'rsat(); // "DevDocs"
console.log(dasturNomi); // ✅ ko'rinadi
Global o'zgaruvchilar qulay ko'rinadi — lekin muammo tug'diradi. Katta loyihalarda qaysi funksiya qaysi global o'zgaruvchini o'zgartirayotganini kuzatish qiyinlashadi. Global o'zgaruvchilar minimallashtiriladi.
Function Scope
var bilan e'lon qilingan o'zgaruvchi — funksiya ichida ko'rinadi, tashqarida yo'q.
function hisoblash() {
var ichki = 10;
console.log(ichki); // ✅ 10
}
hisoblash();
console.log(ichki); // ❌ ReferenceError
var ning muammosi — blok scope ni tushunmaydi:
if (true) {
var x = 5; // ← var blokni e'tiborsiz qoldiradi
}
console.log(x); // 5 — tashqarida ham ko'rinadi!
Shu sababli var ishlatilmaydi — let va const ishlatiladi.
Block Scope
let va const — blok {} ichida e'lon qilinsa, faqat shu blokda ko'rinadi.
if (true) {
let y = 5;
const z = 10;
console.log(y, z); // ✅ 5, 10
}
console.log(y); // ❌ ReferenceError
console.log(z); // ❌ ReferenceError
for sikli ham blok:
for (let i = 0; i < 3; i++) {
// i faqat shu yerda ko'rinadi
}
console.log(i); // ❌ ReferenceError
Nima uchun shunday?
Nima uchun var emas let/const?
var — JavaScript ning eski versiyasidan. Block scope tushunmaydi, hoisting bilan g'alati ishlaydi. let va const bu muammolarni hal qilish uchun ES6 da kiritildi.
// var — xavfli
for (var i = 0; i < 3; i++) { }
console.log(i); // 3 — sikl tashqarisida ham ko'rinadi!
// let — xavfsiz
for (let j = 0; j < 3; j++) { }
console.log(j); // ❌ ReferenceError — to'g'ri xulq
Scope zanjiri — Lexical Scope
Ichki scope tashqi scope dagi o'zgaruvchilarni ko'radi — lekin teskari emas.
const tashqi = "tashqi";
function tashqiFn() {
const oraliq = "oraliq";
function ichkiFn() {
const ichki = "ichki";
console.log(tashqi); // ✅ ko'rinadi — yuqoriga qaraydi
console.log(oraliq); // ✅ ko'rinadi
console.log(ichki); // ✅ ko'rinadi
}
console.log(ichki); // ❌ ReferenceError — pastga qaray olmaydi
}
O'zgaruvchi topilmasa — JavaScript yuqoriga, tashqi scope ga qaraydi. Bu zanjir global scope gacha davom etadi. Topilmasa — ReferenceError.
Shadowing — ustiga yozish
Ichki scope da tashqi scope dagi o'zgaruvchi bilan bir xil nom ishlatilsa — ichki o'zgaruvchi tashqisini "yashiradi":
const ism = "Ali";
function ko'rsat() {
const ism = "Vali"; // ← tashqi "Ali" ni yashiradi
console.log(ism); // "Vali"
}
ko'rsat();
console.log(ism); // "Ali" — tashqi o'zgarmadi
Bu xato emas — lekin chalkashlik tug'dirishi mumkin. Bir xil nomdan qochish yaxshiroq.
Tez-tez uchraydigan xatolar
var bilan sikl va asinxron:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// 3, 3, 3 — var funksiya scope, sikl tugaganda i=3
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// 0, 1, 2 — let block scope, har iteratsiyada yangi i
Global o'zgaruvchini tasodifan yaratish:
function hisoblash() {
natija = 42; // ← let/const yo'q — global bo'lib qoladi!
}
hisoblash();
console.log(natija); // 42 — global, bu xato
Bir xil nom — shadowing chalkashligi:
const data = fetchData();
function qayta_ishlash() {
const data = []; // ← tashqi data ni yashirdi
// ... tashqi data ga murojaat qilib bo'lmaydi
}
Xulosa
Global scope — hamma joydan ko'rinadi. Minimallashtiriladi.
Function scope — var funksiya ichida ko'rinadi. var ishlatilmaydi.
Block scope — let va const {} ichida ko'rinadi. Tashqarida yo'q.
Ichki scope tashqi scope ni ko'radi — teskari emas. O'zgaruvchi topilmasa — yuqoriga qaraladi (scope zanjiri).
Keyingi dars
10-dars: Hoisting — o'zgaruvchi va funksiyalar qanday ko'tariladi