در حال بارگذاری...

حوزهٔ دید

تا اینجا متغیر اعلان کردید، تابع نوشتید و مقدار برگرداندید. یک قاعدهٔ دیگر هم هست: حوزهٔ دید — یعنی از همین‌جا کدام نام‌ها اصلاً دیده می‌شوند و کدام‌ها نه.

حوزهٔ دید یعنی چه

حوزهٔ دید محدودهٔ برنامه است که یک نام در آن زنده است. بیرون آن محدوده، همان املا ممکن است اصلاً دیده نشود — یا به اسم دیگری اشاره کند. مثل برچسب روی دیوار آشپزخانه: داخل آشپزخانه پیداست؛ بیرون کوچه لزوماً نه.

سه نوع روزمره

📊 سراسری، تابعی و بلوکی

نوع نام کجا زندگی می‌کند ابزار معمول کجا دیده می‌شود؟
سراسری (global) بیرون همهٔ تابع‌ها let / const / var در سطح بالا در کل اسکریپت همان صفحه
محلی تابع داخل بدنهٔ تابع پارامتر و متغیر محلی فقط داخل همان تابع
بلوکی داخل { } مثل if یا حلقه let و const فقط داخل همان بلوک

این سه تا بیشترِ کد مبتدی را پوشش می‌دهد. محلیِ تابع خصوصی می‌ماند. نام‌های let و const داخل آکولاد همان‌جا می‌مانند. سراسری مشترک است — برای شمارندهٔ مشترک مفید، اگر همه‌چیز سراسری شود خطرناک.

نام سراسری

javascript
let city = "Tehran";
function showCity() {
console.log(city);
}
showCity();
console.log(city);

نام سراسری بیرون تابع می‌نشیند

city در سطح بالا اعلان شده؛ هم تابع می‌تواند بخواندش هم console.log بعدی. یک‌بار رشته را عوض کنید؛ همه همان مقدار تازه را می‌بینند. فقط وقتی چند بخش واقعاً یک مقدار مشترک می‌خواهند، سراسری بگذارید.

نام محلی داخل تابع

javascript
function greet() {
let message = "Hello";
console.log(message);
}
greet();
// console.log(message); // Error: message is not defined

محلی همان‌جا می‌ماند

message فقط تا وقتی greet اجرا می‌شود وجود دارد. بیرون تابع آن نام تعریف نشده. پارامتر هم همین‌طور است: مالِ همان تابعی است که در () نوشته شده.

حوزهٔ بلوکی با let

javascript
if (true) {
let score = 10;
console.log(score);
}
// console.log(score); // Error: score is not defined

let و const به بلوک احترام می‌گذارند

داخل { }، نامِ let یا const فقط همان بلوک را می‌بیند. بعد از آکولاد بسته، score دیگر نیست. var قدیمی حوزهٔ تابع دارد و ممکن است از بلوک «نشت» کند. let و const را ترجیح بدهید تا لبهٔ بلوک همان معنایی را بدهد که می‌بینید.

کد تو در تو به بیرون می‌خواند

javascript
let title = "Shop";
function show() {
let label = "open";
console.log(title + " is " + label);
}
show();

تو در تو به بیرون نگاه می‌کند

show هم title بیرونی را می‌خواند هم label خودش را. جست‌وجو به سمت بیرون می‌رود تا نام را پیدا کند. برعکس نیست: کد بیرونی نامی را که فقط داخل تابع ساخته شده نمی‌بیند.

نام درونی روی بیرونی سایه می‌اندازد

javascript
let status = "ok";
function check() {
let status = "busy";
console.log(status);
}
check();
console.log(status);

سایه‌اندازی: داخل تابع، نام درونی برنده است

داخل check، status محلی روی بیرونی سایه می‌اندازد. صدا busy چاپ می‌کند. بعد از پایان تابع، status بیرونی هنوز ok است. یک املا، دو نام جدا — حوزهٔ دید مشخص می‌کند کدام را لمس می‌کنید.

مقدار با حوزهٔ دید روی صفحه

یک برچسب سراسری نگه دارید، داخل تابع خطی بسازید که هنوز بتواند آن را بخواند، و نتیجه را در پاراگراف بنویسید.

نمایش صفحه با حوزهٔ دید

html
<!DOCTYPE html>
<html>
<head>
<title>scope — page</title>
</head>
<body>
<p id="msg">…</p>
<script>
let place = "Garden";
function line() {
let state = "open";
return place + " is " + state;
}
let box = document.getElementById("msg");
box.textContent = line();
</script>
</body>
</html>

پاراگراف نشان می‌دهد Garden is open. place سراسری است؛ state محلیِ line است. تابع هر دو را می‌خواند، یک رشته برمی‌گرداند، صفحه همان را نشان می‌دهد. فقط place را عوض کنید، تازه کنید، خط تازه را ببینید. جلسهٔ بعد بستارها (closures) است — وقتی تابع بعد از پایان کار بیرونی هنوز نام‌های بیرونی را یادش می‌ماند.

تمرین

  1. یک let app = "demo" سراسری اعلان کنید و هم از تابع کوچک هم از بیرون لاگ بگیرید.
  2. داخل تابع let secret = 1 بگذارید؛ بیرون لاگ secret باید خطا بدهد.
  3. داخل if (true) { } با let n = 5 بنویسید و لاگ کنید؛ بعد از بلوک دوباره امتحان کنید.
  4. از تابع تو در تو یک let بیرونی را بدون اعلان دوباره بخوانید.
  5. let tag = "A" بیرونی را با let tag = "B" درونی سایه بزنید و هر دو جا را لاگ کنید.
  6. در دموی HTML فقط رشتهٔ place را عوض کنید، تازه کنید، پاراگراف را بخوانید.

اشتباه‌های پرتکرار

  • استفاده از نام محلی بیرون تابع — ReferenceError است، نه صفحهٔ خالی خاموش
  • انتظار اینکه var داخل بلوک مثل let خصوصی بماند
  • فرض اینکه کد بیرونی نام ساخته‌شده فقط داخل تابع تو در تو را می‌بیند
  • قاطی کردن حوزهٔ دید با return — یکی دربارهٔ دیده شدن است، یکی دربارهٔ فرستادن مقدار
  • انتظار درس کامل closures اینجا — زنده ماندن نام بیرونی بعد از پایان صدا موضوع صفحهٔ بعد است

جمع‌بندی

  • حوزهٔ دید جایی است که نام دیده و استفاده می‌شود
  • سراسری بیرون تابع است و در کل اسکریپت مشترک می‌ماند
  • محلی و پارامتر داخل تابع خودشان می‌مانند
  • let و const داخل { } بلوکی‌اند؛ بهتر از var نشت‌کننده
  • کد تو در تو می‌تواند به بیرون بخواند؛ بیرون نام فقط‌درونی را نمی‌بیند
  • نام درونی هم‌املا روی بیرونی سایه می‌اندازد
  • به‌روزرسانی صفحه می‌تواند سراسری و محلی را در یک رشتهٔ برگشتی ترکیب کند
  • بعدی: closures — تابع‌هایی که نام بیرونی را به یاد می‌سپارند

🧠 دانش خود را بیازمایید

آماده شروع

دانش خود را بیازمایید

خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کرده‌اید

❓
8
سوالات
🎯
70%
برای قبولی
♾️
∞
زمان
🔄
∞
تلاش‌ها

📝 دستورالعمل‌ها

  • هر سوال را با دقت بخوانید
  • بهترین پاسخ را برای هر سوال انتخاب کنید
  • می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید
  • پیشرفت شما در بالا نمایش داده می‌شود