المستوى: مبتدئ. الكلام ده موجّه للي لسه بادئ في JavaScript أو بيتعلّم برمجة من شهور قليلة. مش محتاج تكون عارف حاجة عن الـ memory أو الـ compiler عشان تفهمه.
Hoisting في JavaScript: ليه المتغير بيطلّع undefined قبل سطر تعريفه
لو طبعت متغير قبل السطر اللي عرّفته فيه ولقيت الناتج undefined بدل ما الكود يقع بخطأ، انت قابلت الـ Hoisting. المقال ده هيخليك تفهم ليه بيحصل ده بالظبط، وإزاي تكتب كودك بحيث ميفاجئكش تاني.
المشكلة باختصار
شوف الكود ده. منطقيًا المفروض يقع، لأنك بتستخدم x قبل ما تعرّفها:
console.log(x); // إيه اللي هيطبع؟
var x = 5;
console.log(x); // وهنا؟
الناتج الفعلي على Node 22 بيطلع كده:
undefined
5
السطر الأول مرماهوش خطأ، وطبع undefined. ده اللي بيلخبط أي حد بادئ. كأن JavaScript عرفت إن في متغير اسمه x قبل ما توصل لسطر تعريفه. وده بالظبط اللي بيحصل.
افهمها الأول بمثال المخزن
تخيّل عامل في مخزن. قبل ما يبدأ شغل اليوم، بيقرأ ورقة الطلبات كلها مرة واحدة، وبيكتب على رف فاضي أسماء كل الصناديق اللي هيحتاجها النهارده. الرف دلوقتي فيه أسماء بس، من غير محتوى جوه الصناديق.
بعد كده بيبدأ ينفّذ الطلبات سطر سطر. أول ما يوصل لطلب "املأ صندوق x بـ 5 قطع"، ساعتها بس الصندوق بيتملي.
فلو حد سأل العامل عن صندوق x قبل ما يوصل لسطر التعبئة، هيلاقي الاسم موجود على الرف بس الصندوق فاضي. الاسم اتحجز بدري، القيمة لسه متحطتش. الكلمة "فاضي" دي هي undefined في JavaScript.
التعريف العلمي للـ Hoisting
بالتفاصيل: قبل ما JavaScript تشغّل كودك سطر بسطر، بتعمل مرور أولي على الـ scope كله. في المرور ده، بتحجز مكان في الذاكرة لكل تعريفات var وكل function declarations، وبترفعها مفاهيميًا لأعلى الـ scope. ده اللي اسمه Hoisting (الرفع).
المهم اللي لازم يثبت في دماغك: اللي بيتـرفع هو التعريف بس، مش القيمة. يعني الكومبايلر بيفهمها كأنها سطرين منفصلين: