javascriptvar and hoistingvar و بالاکشیدن تعریف در جاوااسکریپت
Hoisting در جاوااسکریپت را با var، let و const بفهمید؛ تفاوت آمادهشدن نام، مقداردهی و ناحیهٔ مردهٔ زمانی را با خروجی واقعی بررسی کنید.
مفهوم به زبان ساده
در کدهای قدیمی ممکن است نامی را پیش از خط var بخوانید و بهجای خطا، undefined ببینید. تعریف var در محدودهٔ تابع پیش از اجرای دستورها شناخته میشود، اما مقداردهی نوشتهشده بعداً فقط هنگام رسیدن اجرا به همان خط انجام میشود. اصطلاح Hoisting توصیفی از این رفتارهاست؛ موتور متن فایل را واقعاً جابهجا نمیکند.
let و const را نباید با همان الگوی var تحلیل کنید. نام آنها در محدودهٔ خود پیش از مقداردهی قابل خواندن نیست؛ فاصلهٔ آغاز محدوده تا مقداردهی را ناحیهٔ مردهٔ زمانی یا TDZ مینامند. خواندن در این فاصله ReferenceError ایجاد میکند، حتی اگر در محدودهٔ بیرونی نام مشابهی موجود باشد. نوشتن «let هم مثل var ابتدا undefined است» توضیح درستی نیست.
در مثال، همهٔ رفتارها داخل یک تابع مستقل رخ میدهد تا به متغیرهای سراسری محیط وابسته نباشد. var محدودهٔ بلوکی ندارد؛ بااینحال در این مدخل هدف تشویق استفاده از آن نیست. تعریف نامها نزدیک محل استفاده، آغاز با const و انتخاب let برای انتساب دوباره، دنبالکردن مسیر داده را سادهتر میکند. دانستن var بیشتر برای خواندن و اصلاح کد موجود مفید است.
کجا به کار میآید؟
- فهمیدن علت undefined در کد قدیمی دارای var
- یافتن دسترسی زودهنگام به let یا const در همان محدوده
از تعریف تا یک مثال واقعی
function inspectDeclarations() {
console.log(score);
var score = 12;
console.log(score);
try {
console.log(limit);
let limit = 20;
} catch (error) {
console.log(error instanceof ReferenceError);
}
}
inspectDeclarations();
undefined 12 true
این مثال چطور کار میکند؟
نام score پیش از مقداردهی موجود است و نخست undefined چاپ میشود.
پس از رسیدن اجرا به انتساب، مقدار ۱۲ دیده میشود.
خواندن limit پیش از مقداردهی، خطای ReferenceError ایجاد میکند.
اشتباه رایج
Hoisting به معنی بالا آمدن مقداردهی نیست. همچنین اجرای typeof روی let در TDZ هم میتواند خطا بدهد؛ این حالت با نامی که اصلاً تعریف نشده فرق دارد.
این را به خاطر بسپارید
تعریف و مقداردهی را جدا تحلیل کنید؛ var و let پیش از خط تعریف، رفتار یکسانی ندارند.