آموزش جامع حوزه بندی در جاوااسکریپت


🎯 اهداف یادگیری

  • درک مفهوم حوزه بندی (Scope) در جاوااسکریپت
  • شناخت تفاوت بین Scope جهانی و محلی
  • آشنایی با حوزه بندی بلوکی (Block Scope)
  • یادگیری مفهوم Hoisting و Temporal Dead Zone

📌 حوزه بندی (Scope) چیست؟

حوزه بندی به محدوده دسترسی متغیرها و توابع در جاوااسکریپت اشاره دارد:

javascript
// متغیر جهانی (Global Scope)
const globalVar = 'من در همه جا قابل دسترس هستم';
function testScope() {
// متغیر محلی (Function Scope)
var localVar = 'من فقط در این تابع قابل دسترس هستم';
console.log(globalVar); // قابل دسترس
}
console.log(localVar); // ارور: localVar تعریف نشده

انواع Scope در جاوااسکریپت:

  • Global Scope: متغیرهای تعریف شده خارج از توابع و بلوک‌ها
  • Function Scope: متغیرهای تعریف شده با var داخل توابع
  • Block Scope: متغیرهای تعریف شده با let و const داخل بلوک‌ها ({})

📌 تفاوت var, let و const در حوزه بندی

نوع تعریف متغیرها بر حوزه دسترسی آنها تأثیر می‌گذارد:

javascript
if (true) {
var functionScoped = 'من با var تعریف شده‌ام';
let blockScopedLet = 'من با let تعریف شده‌ام';
const blockScopedConst = 'من با const تعریف شده‌ام';
}
console.log(functionScoped); // قابل دسترس
console.log(blockScopedLet); // ارور: تعریف نشده
console.log(blockScopedConst); // ارور: تعریف نشده

مقایسه حوزه بندی:

  • var: فقط Function Scope ایجاد می‌کند (نه Block Scope)
  • let/const: Block Scope ایجاد می‌کنند (محدود به بلوک تعریف)
  • بدون تعریف: متغیرهای بدون تعریف (مثلاً x = 10) همیشه Global هستند

📌 زنجیره حوزه بندی (Scope Chain)

جاوااسکریپت برای یافتن متغیرها از زنجیره حوزه بندی استفاده می‌کند:

javascript
const global = 'من جهانی هستم';
function outer() {
const outerVar = 'من در تابع بیرونی هستم';
function inner() {
const innerVar = 'من در تابع درونی هستم';
console.log(innerVar); // دسترسی به متغیر خود
console.log(outerVar); // دسترسی به متغیر والد
console.log(global); // دسترسی به متغیر جهانی
}
inner();
}
outer();

مکانیزم جستجوی Scope:

  • جستجوی داخلی به خارجی: ابتدا Scope فعلی، سپس والد و در نهایت Global
  • عدم دسترسی خارج به داخل: Scopeهای داخلی از بیرون قابل دسترس نیستند
  • ایجاد Closure: توابع داخلی می‌توانند به Scope والد حتی پس از اتمام آن دسترسی داشته باشند

📌 Hoisting و Temporal Dead Zone

رفتار خاص جاوااسکریپت در مورد تعریف متغیرها قبل از اختصاص مقدار:

javascript
// Hoisting با var
console.log(hoistedVar); // undefined (ارور نمی‌دهد)
var hoistedVar = 'من با var تعریف شده‌ام';
// Temporal Dead Zone با let/const
console.log(notHoistedLet); // ارور: قبل از تعریف قابل دسترس نیست
let notHoistedLet = 'من با let تعریف شده‌ام';

مفاهیم کلیدی:

  • Hoisting: جاوااسکریپت تعاریف var و function را به بالای Scope می‌برد (با مقدار undefined برای var)
  • Temporal Dead Zone (TDZ): محدوده بین شروع بلوک و نقطه تعریف واقعی برای let/const که دسترسی به متغیر ارور می‌دهد
  • بهترین روش: همیشه متغیرها را قبل از استفاده تعریف کنید

📌 تمرین عملی

کد زیر را تحلیل کنید و پیش‌بینی کنید چه خروجی‌هایی خواهد داشت:

javascript
let x = 10;
function outer() {
console.log(x); // ?
let x = 20;
console.log(x); // ?
}
outer();
console.log(x); // ?

راهنمای تمرین:

  1. اولین console.log در تابع outer چه خروجی می‌دهد؟ چرا؟
  2. آیا تغییر x در تابع outer بر متغیر جهانی x تأثیر می‌گذارد؟
  3. اگر let را به var تغییر دهیم، رفتار چگونه تغییر می‌کند؟

📌 قدم بعدی

در درس بعدی با آشنا خواهیم شد!