در جاوااسکریپت 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 و اجتناب از مشکلات مربوط به آن، میتوانید کد جاوااسکریپت خود را به شکلی پایدارتر و قابل نگهداریتر بنویسید.