
در جاوااسکریپت Hoisting یکی از مفاهیم مهم در جاوااسکریپت است که ممکن است منجر به رفتار غیرمنتظره در کد شود. این مکانیزم باعث میشود تا اعلانهای متغیرها، توابع و کلاسها به بالای محدوده خود منتقل شوند، حتی قبل از اجرای کد. به عبارت دیگر، اعلان (Declarations) متغیرها و توابع به بالای محدوده خود منتقل میشوند، اما مقداردهیها (Initializations) در جای خود باقی میمانند.
در جاوااسکریپت، متغیرهایی که با var تعریف میشوند، تنها اعلان آنها به بالای محدوده منتقل میشود، اما مقداردهی آنها نه. این یعنی اگر پیش از مقداردهی از متغیری استفاده کنید، مقدار آن undefined خواهد بود.
console.log(foo); // undefined var foo = 'bar';
در اینجا، foo به بالای محدوده منتقل شده اما مقداردهی نشده است، بنابراین خروجی undefined خواهد بود.
let و const :با معرفی let و const در ES6، رفتار متفاوتی نسبت به var اعمال شد. در اینجا متغیرها به منطقه زمانی مرده (Temporal Dead Zone) وارد میشوند و اگر پیش از اعلان از آنها استفاده شود، خطای ReferenceError رخ خواهد داد.
console.log(bar); // ReferenceError let bar = 'baz';
توابع در جاوااسکریپت به دو صورت تعریف میشوند: اعلان توابع (Function Declarations) و تعبیر توابع (Function Expressions).
اعلان توابع بهطور کامل به بالای محدوده منتقل میشود، به همین دلیل میتوان آنها را قبل از اعلام فراخوانی کرد:
hoistedFunction(); // Outputs: "This function has been hoisted." function hoistedFunction() { console.log("This function has been hoisted."); }
عبیر توابع، مانند توابعی که با var, let, یا const تعریف میشوند، تنها اعلام متغیر به بالا منتقل میشود، اما مقداردهی (تعریف تابع) نه :
console.log(notHoistedFunction); // undefined var notHoistedFunction = function() { console.log("This function expression is not hoisted."); };
در اینجا، notHoistedFunction به بالا منتقل شده اما مقداردهی نشده است، بنابراین مقدار undefined خواهد بود.
کلاسها نیز مشابه با let و const، تنها اعلانشان به بالا منتقل میشود و اگر قبل از اعلام کلاس از آن استفاده شود، خطای ReferenceError رخ میدهد :
const p = new Rectangle(); // ReferenceError class Rectangle {}
میتواند Hoisting باعث بروز رفتارهای غیرمنتظره در کد شود، بهخصوص اگر متغیری را دو بار اعلام کنید. این امر میتواند باعث بازنویسی اعلامهای قبلی شده و اشکالزدایی را در پروژههای بزرگ دشوار کند.
برای جلوگیری از مشکلات مربوط به Hoisting:
let یا const به جای var استفاده کنید. این باعث میشود که متغیرها در منطقه زمانی مرده قرار گیرند و خطاهای احتمالی شناسایی شوند.دو دلیل اصلی برای پیادهسازی Hoisting در جاوااسکریپت وجود دارد:
یکی از ویژگیهای قدرتمند جاوااسکریپت Hoisting است، اما میتواند در صورتی که به درستی مدیریت نشود، منجر به بروز مشکلاتی شود. با درک درست از نحوه عملکرد Hoisting و اجتناب از مشکلات مربوط به آن، میتوانید کد جاوااسکریپت خود را به شکلی پایدارتر و قابل نگهداریتر بنویسید.