Execution Context والـ Call Stack — إزاي JS بيشغّل كودك فعلاً
ليه الدرس ده؟ ده أول سؤال بيفرّق بين "بستخدم JS" و"فاهم JS" في أي انترفيو محترم — وهو الأساس اللي هيتبني عليه فهمك لـ hoisting والـ closures والـ event loop في الأسابيع الجاية إن شاء الله.
🔁 قبل ما تبدأ: ده أول درس في الرحلة — مفيش prerequisites غير أساسيات JS اللي معاك من شغلك. ادخل على طول.
١ — الفكرة في 3 جمل
① كل ما JS يبدأ يشغّل كود، بيعمل حاجة اسمها Execution Context — "بيئة تنفيذ" فيها كل اللي الكود محتاجه (المتغيرات، الـ scope، قيمة this).
② أول ما البرنامج يبدأ بيتعمل Global Execution Context واحد، وكل استدعاء لأي function بيعمل execution context جديد خاص بيها.
③ الـ contexts دي بتترص فوق بعض في Call Stack: اللي بيتنفذ دلوقتي هو اللي فوق خالص، ولما يخلّص بيتشال — آخر واحد دخل، أول واحد يخرج (ودي اللي بيسموها LIFO = Last In, First Out).
٢ — كل context بيتعمل على مرحلتين
دي النقطة اللي أغلب الجونيورز مش واخدين بالهم منها، وهي مفتاح فهم الـ hoisting (درسنا الجاي إن شاء الله):
مرحلة الإنشاء (Creation): قبل تنفيذ أي سطر، المحرك بيمسح الكود وبيحجز مكان للمتغيرات والدوال في الذاكرة.
مرحلة التنفيذ (Execution): الكود بيتنفذ سطر سطر والقيم بتتحط في الأماكن المحجوزة.
خد بالك: وجود المرحلتين دول هو السبب الحقيقي إن var بتظهر بقيمة undefined قبل سطر تعريفها. هنشرّح ده في درس 0002 إن شاء الله.
٣ — شوفها بعينك: محاكي الـ Call Stack
الكود ده هنمشيه سطر سطر. دوس «خطوة» وراقب حاجتين مع بعض: الـ Call Stack من بره (مين داخل ومين خارج)، وجوه كل context — المتغيرات وقيمها بتتغير لحظة بلحظة (الأصفر = اتغير حالاً، ⏳ = محجوز في مرحلة الإنشاء ولسه ماخدش قيمة). وحاول تتوقع قبل كل ضغطة إيه اللي هيحصل:
function greet(name) { const msg = build(name); console.log(msg); } function build(name) { return "أهلاً يا " + name; } greet("عمر");
٤ — Stack Overflow مش بس اسم موقع
الـ stack ليه حجم محدود. لو function فضلت تنادي نفسها من غير نقطة توقف، الـ frames هتتراكم لحد ما المساحة تخلص — وده الخطأ الشهير:
function boom() { boom(); }
boom(); // RangeError: Maximum call stack size exceeded
لما تشوف الرسالة دي في شغلك، دلوقتي بقيت عارف معناها الحرفي: الـ call stack اتملى عن آخره.
٥ — اختبر نفسك (من غير ما ترجع فوق!)
المحاولة من الذاكرة هي اللي بتثبّت المعلومة — جاوب الأول، وبعدين هتاخد التصحيح فوراً.
س1: الـ Call Stack بيشتغل بأي نظام؟
س2: (بعيداً عن الـ Global context اللي بيتعمل مرة واحدة عند تحميل السكريبت) — امتى بيتعمل Execution Context جديد لدالة؟
س3: إيه اللي هيتطبع من الكود ده بالترتيب؟
function a() {
console.log(1);
b();
console.log(3);
}
function b() { console.log(2); }
a();
س4: في المحاكي فوق، لحظة تنفيذ سطر return "أهلاً يا " + name — كام context موجود في الـ stack؟
٦ — التحدي الأخير: اشرحها بصوت عالي
ده تمرين من الـ roadmap بتاعك نفسه (مهمة "explain"). اقفل الصفحة دي، وسجّل صوتك أو اشرح لحد قدامك:
"لما بكتب myFunction() في JS — إيه اللي بيحصل بالظبط من اللحظة دي لحد ما السطر اللي بعديها يشتغل؟"
الإجابة الكاملة المفروض تلمس: إنشاء context جديد → دخوله الـ stack → التنفيذ → خروجه من الـ stack → الرجوع للـ context اللي تحتيه. لو اتلخبطت في أي جزء، ده بالظبط الجزء اللي ترجع تراجعه.
٧ — المصدر الأساسي للتعمق
اقرأ النص ده (15-20 دقيقة) لتثبيت الدرس — أفضل شرح مكتوب مجاني للموضوع:
- javascript.info — Recursion and stack — اقرأ جزء "The execution context and stack" بالذات.
- MDN — Call Stack — التعريف المرجعي الرسمي.
- ورقة المراجعة السريعة: reference/js-execution-model.html