حوزهٔ دید
تا اینجا متغیر اعلان کردید، تابع نوشتید و مقدار برگرداندید. یک قاعدهٔ دیگر هم هست: حوزهٔ دید — یعنی از همینجا کدام نامها اصلاً دیده میشوند و کدامها نه.
حوزهٔ دید یعنی چه
حوزهٔ دید محدودهٔ برنامه است که یک نام در آن زنده است. بیرون آن محدوده، همان املا ممکن است اصلاً دیده نشود — یا به اسم دیگری اشاره کند. مثل برچسب روی دیوار آشپزخانه: داخل آشپزخانه پیداست؛ بیرون کوچه لزوماً نه.
سه نوع روزمره
📊 سراسری، تابعی و بلوکی
| نوع | نام کجا زندگی میکند | ابزار معمول | کجا دیده میشود؟ |
|---|---|---|---|
| سراسری (global) | بیرون همهٔ تابعها | let / const / var در سطح بالا |
در کل اسکریپت همان صفحه |
| محلی تابع | داخل بدنهٔ تابع | پارامتر و متغیر محلی | فقط داخل همان تابع |
| بلوکی | داخل { } مثل if یا حلقه |
let و const |
فقط داخل همان بلوک |
این سه تا بیشترِ کد مبتدی را پوشش میدهد. محلیِ تابع خصوصی میماند. نامهای let و const داخل آکولاد همانجا میمانند. سراسری مشترک است — برای شمارندهٔ مشترک مفید، اگر همهچیز سراسری شود خطرناک.
let city = "Tehran";
function showCity() {
console.log(city);
}
showCity();
console.log(city);
نام سراسری بیرون تابع مینشیند
city در سطح بالا اعلان شده؛ هم تابع میتواند بخواندش هم console.log بعدی. یکبار رشته را عوض کنید؛ همه همان مقدار تازه را میبینند. فقط وقتی چند بخش واقعاً یک مقدار مشترک میخواهند، سراسری بگذارید.
function greet() {
let message = "Hello";
console.log(message);
}
greet();
// console.log(message); // Error: message is not defined
محلی همانجا میماند
message فقط تا وقتی greet اجرا میشود وجود دارد. بیرون تابع آن نام تعریف نشده. پارامتر هم همینطور است: مالِ همان تابعی است که در () نوشته شده.
if (true) {
let score = 10;
console.log(score);
}
// console.log(score); // Error: score is not defined
let و const به بلوک احترام میگذارند
داخل { }، نامِ let یا const فقط همان بلوک را میبیند. بعد از آکولاد بسته، score دیگر نیست. var قدیمی حوزهٔ تابع دارد و ممکن است از بلوک «نشت» کند. let و const را ترجیح بدهید تا لبهٔ بلوک همان معنایی را بدهد که میبینید.
let title = "Shop";
function show() {
let label = "open";
console.log(title + " is " + label);
}
show();
تو در تو به بیرون نگاه میکند
show هم title بیرونی را میخواند هم label خودش را. جستوجو به سمت بیرون میرود تا نام را پیدا کند. برعکس نیست: کد بیرونی نامی را که فقط داخل تابع ساخته شده نمیبیند.
let status = "ok";
function check() {
let status = "busy";
console.log(status);
}
check();
console.log(status);
سایهاندازی: داخل تابع، نام درونی برنده است
داخل check، status محلی روی بیرونی سایه میاندازد. صدا busy چاپ میکند. بعد از پایان تابع، status بیرونی هنوز ok است. یک املا، دو نام جدا — حوزهٔ دید مشخص میکند کدام را لمس میکنید.
مقدار با حوزهٔ دید روی صفحه
یک برچسب سراسری نگه دارید، داخل تابع خطی بسازید که هنوز بتواند آن را بخواند، و نتیجه را در پاراگراف بنویسید.
<!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) است — وقتی تابع بعد از پایان کار بیرونی هنوز نامهای بیرونی را یادش میماند.
تمرین
- یک
let app = "demo"سراسری اعلان کنید و هم از تابع کوچک هم از بیرون لاگ بگیرید. - داخل تابع
let secret = 1بگذارید؛ بیرون لاگsecretباید خطا بدهد. - داخل
if (true) { }باlet n = 5بنویسید و لاگ کنید؛ بعد از بلوک دوباره امتحان کنید. - از تابع تو در تو یک
letبیرونی را بدون اعلان دوباره بخوانید. let tag = "A"بیرونی را باlet tag = "B"درونی سایه بزنید و هر دو جا را لاگ کنید.- در دموی HTML فقط رشتهٔ
placeرا عوض کنید، تازه کنید، پاراگراف را بخوانید.
اشتباههای پرتکرار
- استفاده از نام محلی بیرون تابع — ReferenceError است، نه صفحهٔ خالی خاموش
- انتظار اینکه
varداخل بلوک مثلletخصوصی بماند - فرض اینکه کد بیرونی نام ساختهشده فقط داخل تابع تو در تو را میبیند
- قاطی کردن حوزهٔ دید با
return— یکی دربارهٔ دیده شدن است، یکی دربارهٔ فرستادن مقدار - انتظار درس کامل closures اینجا — زنده ماندن نام بیرونی بعد از پایان صدا موضوع صفحهٔ بعد است
جمعبندی
- حوزهٔ دید جایی است که نام دیده و استفاده میشود
- سراسری بیرون تابع است و در کل اسکریپت مشترک میماند
- محلی و پارامتر داخل تابع خودشان میمانند
letوconstداخل{ }بلوکیاند؛ بهتر ازvarنشتکننده- کد تو در تو میتواند به بیرون بخواند؛ بیرون نام فقطدرونی را نمیبیند
- نام درونی هماملا روی بیرونی سایه میاندازد
- بهروزرسانی صفحه میتواند سراسری و محلی را در یک رشتهٔ برگشتی ترکیب کند
- بعدی: closures — تابعهایی که نام بیرونی را به یاد میسپارند
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود