Хамрах хүрээ (Scope)
Scope нь хувьсагч хаанаас харагдах, хаанаас харагдахгүйг тодорхойлдог дүрэм юм. Хувьсагч бүр зарлагдсан газраасаа хамааран тодорхой "хамрах хүрээ" (scope)-тай байдаг. Scope-г сайн ойлгох нь алдаа олоход, код зохион байгуулахад маш чухал.
Global scope — бүх газрын хувьсагч
Ямар нэг функц эсвэл блокоос гадна зарласан хувьсагч global scope-д байдаг — кодын аль ч газраас харагдана.
const siteName = "Ulaanbaatar.app"; // global
function showSite() {
console.log(siteName); // ✅ Харагдана
}
function greetUser(name) {
console.log(`${name} — ${siteName} дээр тавтай морил!`); // ✅ Харагдана
}
showSite(); // Ulaanbaatar.app
greetUser("Болд"); // Болд — Ulaanbaatar.app дээр тавтай морил!
Global хувьсагч дурын газраас харагддаг боловч хэт олон global хувьсагч бичих нь кодыг хяналтгүй болгодог. Шаардлагагүй бол global-ыг аль болох цөөлөх нь сайн заншил.
Local scope — функцийн дотор хувьсагч
Функц дотор зарласан хувьсагч тэр функцийн local scope-д байдаг — гаднаас харагдахгүй.
function calculateXP(lessons) {
const bonusMultiplier = 1.5; // local — зөвхөн энд харагдана
return lessons * 10 * bonusMultiplier;
}
console.log(calculateXP(5)); // 75
console.log(bonusMultiplier); // ❌ Алдаа — гаднаас харагдахгүй
Функц бүр өөрийн private орон зай үүсгэдэг — энэ нь нэр давхцах, санамсаргүй өөрчлөгдөх зэрэг алдаанаас сэргийлдэг.
Block scope — let ба const
{} хаалтаар үүсгэсэн блок дотор let эсвэл const-ээр зарласан хувьсагч зөвхөн тэр блокт харагдана. Үүнийг block scope гэдэг.
if (true) {
let message = "Блок дотор"; // block scope
const code = 42;
console.log(message); // ✅ Болно
}
console.log(message); // ❌ Алдаа — блокоос гадна харагдахгүй
console.log(code); // ❌ Алдаа
// for давталтад ч адил
for (let i = 0; i < 3; i++) {
// i зөвхөн энд харагдана
}
console.log(i); // ❌ Алдаа
var — block scope байхгүй, яагаад аюултай вэ?
var нь block scope дагаддаггүй — {} хаалтыг нэвтэрч гардаг. Энэ нь гэнэтийн алдааны эх сурвалж болдог.
if (true) {
var oldVar = "var хуучин";
let newLet = "let шинэ";
}
console.log(oldVar); // ✅ "var хуучин" — блокоос гарсан!
console.log(newLet); // ❌ Алдаа — зөв зан авир
// for давталтад var ашиглах аюул
for (var i = 0; i < 3; i++) {
// ...
}
console.log(i); // 3 — var давталтаас "алдарсан"
Яг энэ учраас var ашиглахаа больж, let ба const ашиглахыг зөвлөдөг.
Scope гинж — дотроос гадагш хайх
Хувьсагчийг хайхдаа JavaScript нь эхлээд дотоод scope-оос хайж, олдохгүй бол гаднах scope руу ахидаг. Энэ дарааллыг scope chain гэдэг.
const level = 1; // global
function getStatus() {
const level = 5; // local — global-ыг далдалдаг
console.log(level); // 5 — local-ыг олоод зогсоно
}
function showGlobal() {
console.log(level); // 1 — local байхгүй тул global-ыг авна
}
getStatus(); // 5
showGlobal(); // 1
const xp = 0; // global
function updatePlayer() {
const xp = 100; // local — global-ыг нуудаг
function applyBonus() {
const bonus = 50;
console.log(xp + bonus); // 150 — дотроос гадагш хайж xp=100 олно
}
applyBonus();
}
updatePlayer(); // 150
Дотор функц нь гаднах функцийн хувьсагчийг харж чаддаг — энэ нь closure-ын суурь ойлголт бөгөөд дараагийн хичээлд дэлгэрэнгүй үзнэ.
Дараагийн хичээлд:
Closure — функц өөрийгөө үүсгэсэн орчны хувьсагчдыг хэрхэн "санаж" үлддэгийг судлана. JavaScript-ийн хамгийн гүн ойлголтуудын нэг.