JavaScript’da Lexical Environment (Scoping) va Closure
JavaScript — kuchli, ammo ba’zan murakkab til. Ayniqsa, closure va lexical scope kabi tushunchalar ko‘pchilikni chalkashtirib yuboradi. Ushbu maqolada siz bu tushunchalarni nafaqat nazariy, balki amaliy misollar orqali ham chuqur tushunib olasiz.
Bu maqolada siz quyidagilarni o'rganasiz :
- Lexical Environment nima?
- Scope turlari (Global, Function, Block)
- Closure nima va qanday ishlaydi?
- 5 ta amaliy misollar bilan mustahkamlash.
1. Lexical Environment nima?
Har bir JavaScript funksiyasi ishlayotganida o‘zining lexical environmentiga ega bo‘ladi. Bu environment 2 ta asosiy qismdan iborat:
- Environment Record – o‘zgaruvchilar va funksiyalar haqida ma’lumot saqlanadigan qism.
- Outer Lexical Environment Reference – tashqi (ya’ni yuqoridagi) scope’ga bog‘lanadi.
JavaScript’da bu struktura chain-like scope resolution ni tashkil qiladi.
2. Scoping turlari
Scope - o’zgaruvchi va funksiyalar qayerda ko’rinish/ko’rinmasligini aniqlab beruvchi tushuncha.
Global - Har joyda mavjud
Function - Faqat funksiyada ko‘rinadi
Block - {} ichida (let, const o'zgaruvchilar bunga misol)
Misol 1: Global va Function scope
var globalVar = "I'm global";
function example() {
let localVar = "I'm local";
console.log(globalVar); // "I'm global"
console.log(localVar); // "I'm local"
}
example();
// console.log(localVar); // ReferenceError: localVar is not definedBu yerdalocalVarfaqatexamplefunksiyasi ichida mavjud. Tashqarida unga murojaat qilib bo‘lmaydi
Misol 2: Block scope ( var, let, const)
function blockScopeExample() {
if (true) {
let a = 42;
const b = 100;
var c = 123
console.log(a, b); // 42 100
}
// console.log(a); // ReferenceError
// console.log(b); // ReferenceError
// console.log(c); // 123
}
blockScopeExample();letvaconst{} block-scoped bo'lganligi uchun u yaratilgan blokdan tashqarida murojat qilib bo'lmaydi.varesa function-scoped bo‘lib,{}blok scope dan tashqaridagi function ning lexical environmentida yaratiladi va function ichida murojat qilish mumkin.
3. Closure nima?
Closure – bu funksiya o‘zining tashqi lexical environmentiga murojaat qilishi mumkin bo‘lgan holatdir, hatto bu tashqi funksiyaga ishlab tugagan bo‘lsa ham.
Oddiy qilib aytganda: “Ichki funksiya tashqi funksiyadagi o‘zgaruvchilarni eslab qoladi.”
function outer() {
let count = 0;
return function inner() {
count++;
console.log("Count:", count);
};
}
const counter = outer();
counter(); // Count: 1
counter(); // Count: 2innerfunksiyasioutertugagan bo‘lsa ham,counto‘zgaruvchisini eslab qolgan.
Misol 4: Closure bilan private o‘zgaruvchilar yaratish
function createUser(name) {
let secret = "My password is 123";
return {
getName: () => name,
revealSecret: () => secret
};
}
const user = createUser("Aziz");
console.log(user.getName()); // Aziz
console.log(user.revealSecret()); // My password is 123Bu usul orqali JavaScript’da encapsulation (yashirish) amalga oshiriladi va bu orqali private variable lar yaratish mumkin.
Misol 5: Loop va Closure muammosi va yechimi (Interview larda ko'p so'raladigan savollardan biri)
// noto‘g‘ri
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log("Wrong:", i), 100);
}
natija: 3,3,3
// Yechimi: `let` dan foydalanish
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log("Correct:", i), 100);
}
natija: 1,2,3var— function-scoped (yoki global agar funksiya ichida bo‘lmasa), shuning uchun butunforsikli davomida bittaio‘zgaruvchisi mavjud bo‘ladi.
setTimeoutorqali kechiktirilgan funksiya esa, loop tugagach (i = 3bo‘lganida) ishga tushadi va har uchalasida hami = 3bo‘ladi.,letesa har bir iteratsiyada yangi lexical environment yaratadi.