JavaScript үндэс / Хамрах хүрээ (Scope)

Хамрах хүрээ (Scope)

Scope нь хувьсагч хаанаас харагдах, хаанаас харагдахгүйг тодорхойлдог дүрэм юм. Хувьсагч бүр зарлагдсан газраасаа хамааран тодорхой "хамрах хүрээ" (scope)-тай байдаг. Scope-г сайн ойлгох нь алдаа олоход, код зохион байгуулахад маш чухал.

Global scope — бүх газрын хувьсагч

Ямар нэг функц эсвэл блокоос гадна зарласан хувьсагч global scope-д байдаг — кодын аль ч газраас харагдана.

javascript
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-д байдаг — гаднаас харагдахгүй.

javascript
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 гэдэг.

javascript
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 дагаддаггүй — {} хаалтыг нэвтэрч гардаг. Энэ нь гэнэтийн алдааны эх сурвалж болдог.

javascript
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 гэдэг.

javascript
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
javascript
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-ийн хамгийн гүн ойлголтуудын нэг.