كيف تجتاز مقابلة JavaScript: أهم الأسئلة من الألف إلى الياء
\n\nمقابلة مطور JavaScript ليست مجرد اختبار للقواعد النحوية. يرغب أصحاب العمل في رؤية فهم عميق للغة وخصائصها والقدرة على العمل مع العمليات غير المتزامنة. في هذه المقالة، سنحلل الموضوعات الرئيسية التي ستساعدك على اجتياز المقابلة بثقة. سنتناول الأسئلة من المفاهيم الأساسية إلى الموضوعات المتقدمة في Node.js مع أمثلة كود حقيقية.
\n\n1. الأساسيات: أنواع البيانات، hoisting ونطاقات الرؤية
\n\nلنبدأ بالأساسيات. JavaScript هي لغة ذات كتابة ديناميكية. فهم var و let و const هو الحد الأدنى الإلزامي.
سؤال: ما الفرق بين var و let و const؟
- \n
varله نطاق رؤية وظيفي ويتم رفعه (hoisting) بقيمةundefined. \n letوconstلهما نطاق رؤية كتلي ولا يتم تهيئتهما حتى الإعلان (المنطقة الميتة المؤقتة). \n constيمنع إعادة التعيين، لكنه لا يجعل الكائن غير قابل للتغيير. \n
مثال على hoisting:
\nconsole.log(a); // undefined (hoisting)\nvar a = 5;\n\nconsole.log(b); // ReferenceError: Cannot access 'b' before initialization\nlet b = 10;\n\nسؤال: ما هو "الرفع" (hoisting)؟
\nهي آلية يتم من خلالها نقل إعلانات المتغيرات والدوال إلى بداية نطاق الرؤية الخاص بها قبل تنفيذ الكود. الدوال المعلنة عبر function تُرفع بالكامل، بينما المتغيرات تُرفع فقط الإعلان وليس التهيئة.
2. الإغلاقات والسياق (this)
\n\nالإغلاقات هي واحدة من أقوى جوانب JavaScript. تسمح للدالة بتذكر البيئة المعجمية التي تم إنشاؤها فيها.
\n\nسؤال: ما هو الإغلاق؟ أعط مثالاً.
\nالإغلاق هو مزيج من دالة وبيئتها المعجمية. بمعنى آخر، الدالة الداخلية لديها إمكانية الوصول إلى متغيرات الدالة الخارجية حتى بعد انتهاء الدالة الخارجية من العمل.
\n\nfunction createCounter() {\n let count = 0;\n return function() {\n count++;\n return count;\n };\n}\n\nconst counter = createCounter();\nconsole.log(counter()); // 1\nconsole.log(counter()); // 2\n\nسؤال: كيف يعمل this في JavaScript؟
يتم تحديد قيمة this من خلال كيفية استدعاء الدالة، وليس من خلال مكان إعلانها. القواعد الأساسية:
- \n
- في السياق العام (في المتصفح) —
window، في Node.js —global. \n - في طريقة كائن — الكائن نفسه. \n
- في دالة تم استدعاؤها عبر
new— مثيل جديد. \n - عند استخدام
callأوapplyأوbind— الكائن المُمرر. \n - في دوال السهم —
thisمأخوذ من السياق المعجمي الخارجي. \n
const obj = {\n name: 'Alice',\n greet() {\n console.log(this.name);\n }\n};\n\nconst greet = obj.greet;\ngreet(); // undefined (فقدان السياق)\n\nconst boundGreet = obj.greet.bind(obj);\nboundGreet(); // Alice\n\n3. العمليات غير المتزامنة: Event Loop، البروميس و async/await
\n\nJavaScript هي لغة ذات خيط واحد، لكنها تعالج العمليات غير المتزامنة بكفاءة بفضل Event Loop. هذا هو أحد أكثر الموضوعات شيوعًا في المقابلات.
\n\nسؤال: ما هو Event Loop وكيف يعمل؟
\nEvent Loop هو حلقة لا نهائية تراقب مكدس الاستدعاءات (Call Stack) وطوابير المهام (Task Queue / Microtask Queue). إذا كان المكدس فارغًا، فإنه يأخذ المهمة الأولى من طابور المهام الصغيرة (Promise, MutationObserver) أو المهام الكبيرة (setTimeout, I/O).
\n\nسؤال: ما الفرق بين المهام الصغيرة والمهام الكبيرة؟
\n- \n
- المهام الصغيرة: Promise.then/catch/finally،