الرفع في جافا سكريبت
الرفع هو سلوك يتم فيه نقل إعلانات الوظائف والمتغيرات (أو "رفعها") إلى أعلى النطاق المحتوي (إما النطاق العام أو نطاق الوظيفة) قبل يتم تنفيذ الكود. هذا يعني أنه يمكنك استخدام المتغيرات والوظائف قبل أن يتم الإعلان عنها فعليًا في الكود.
الرفع في المتغيرات
فار
- يتم رفع المتغيرات المعلنة باستخدام var إلى أعلى نطاقها، ولكن لا تتم تهيئة قيمها حتى النقطة في الكود حيث يحدث التعيين.
console.log(x); // undefined
var x = 5;
console.log(x); // 5
اسمحوا وثابت
- يتم أيضًا رفع المتغيرات المعلنة باستخدام Let وconst ولكن يتم وضعها في "منطقة ميتة مؤقتة" حتى يتم الوصول إلى إعلاناتها. سيؤدي الوصول إليها قبل الإعلان عنها إلى حدوث خطأ مرجعي.
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
// block scope
{
let x = 5;
}
console.log(x); // ReferenceError: x is not defined
الرفع في الوظائف
الوظيفة التقليدية
- تم رفع إعلانات الوظائف بالكامل، مما يعني نقل كل من الإعلان ونص الوظيفة إلى أعلى النطاق. يتيح لك هذا استدعاء دالة قبل الإعلان عنها في الكود.
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
- في المقابل، يتم رفع التعبيرات الوظيفية (حيث يتم تعيين دالة لمتغير) كمتغيرات فقط، لذا فإن استدعائها قبل تهيئة المتغير سيؤدي إلى خطأ غير محدد أو TypeError.
greet(); // TypeError: greet is not a function
var greet = function () {
console.log("Hi!");
};
greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
console.log("Hi!");
};
وظيفة السهم
- في المقابل، يتم رفع التعبيرات الوظيفية (حيث يتم تعيين دالة لمتغير) كمتغيرات فقط، لذا فإن استدعائها قبل تهيئة المتغير سيؤدي إلى خطأ غير محدد أو TypeError.
greet(); // TypeError: greet is not a function
var greet = () => {
console.log("Hi!");
};
greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
console.log("Hi!");
};
المنطقة الميتة الزمنية (TDZ)
توجد المنطقة الميتة المؤقتة (TDZ) للمتغيرات المعلنة باستخدام Let وconst لأن JavaScript مصمم لمنعك من الوصول إلى هذه المتغيرات قبل الإعلان عنها وتهيئتها.
لماذا var و Let, const يتصرفان بشكل مختلف في الرفع
- ذلك بسبب التطور التاريخي في جافا سكريبت.
- في البداية، تم تصميم JavaScript للمستخدمين الذين ليسوا مطورين، وكان الاستخدام الأساسي الرئيسي لـ JavaScript هو إضافة عناصر تفاعلية صغيرة إلى صفحة الويب.
- لذلك يدعم var النطاق الوظيفي فقط. وفي ذلك الوقت أيضًا، لم يكن هناك نطاق حظر.
- ولكن في التطور اللاحق لجافا سكريبت، أصبح العمل مع var وإصلاح الأخطاء أكثر تعقيدًا.
- ولذلك لجعل جافا سكريبت قادرة على المنافسة مع اللغات الحديثة الأخرى، تمت إضافة المزيد من الميزات مثل Let، const، وظائف السهم، طرق ES6، إلخ.
لماذا لا يتم تحديث var مثل Let وconst
- ذلك بسبب التوافق مع الإصدارات السابقة.
- في ذلك الوقت، تم استخدام JavaScript على نطاق واسع من قبل العديد من المؤسسات، لذا فإن تحديث أو إجراء تغييرات في الميزات الحالية قد يؤدي إلى كسر قاعدة التعليمات البرمجية.
- ولذلك، تمت إضافة الميزات الحديثة بشكل فردي.
أسئلة المقابلة الشائعة
- ما هو الرفع في جافا سكريبت؟
- ما الذي يتم رفعه في جافا سكريبت، وما لا يتم رفعه؟
- ما الفرق بين var و Let و const فيما يتعلق بالرفع؟
- ما هي المنطقة الميتة المؤقتة (TDZ) في جافا سكريبت؟
- هل يمكنك شرح الرفع باستخدام إعلانات الوظائف مقابل تعبيرات الوظائف؟
- ما هو الرفع في وحدات ES6؟
- لماذا يجب علينا تجنب الاعتماد على الرفع في كود العالم الحقيقي؟
ملخص
- الرفع هو السلوك الافتراضي في JavaScript حيث يتم نقل إعلانات المتغيرات والوظائف إلى أعلى النطاقات الخاصة بها أثناء مرحلة التجميع.
- يعمل الرفع فقط مع المتغيرات المعلنة باستخدام الدوال var والتقليدية، وليس مع الدوال Let وconst والسهم.
- يتم رفع إعلان الوظيفة فقط، لذلك تعمل الوظائف التقليدية، ولكن إذا تم تعيين الوظيفة لمتغير، فلن تكون قابلة للاستدعاء حتى يتم تعريفها.
- السبب وراء رفع الدوال var والتقليدية وعدم رفع الدوال Let وconst وarrow هو أنه في المرحلة الأولية، تم استخدام JavaScript في الغالب لتفاعلات واجهة المستخدم الصغيرة.
- ولكن لاحقًا، نظرًا لاستخدام JavaScript على نطاق واسع لبناء التطبيقات من قبل المؤسسات، أصبح من الصعب إصلاح الأخطاء على نطاق عالمي فقط.
- لذا، تمت معالجة المخاوف الأكثر أمانًا في التحديثات المستقبلية.
- بالإضافة إلى ذلك، فإن تحديث الميزات الحالية قد يؤدي إلى كسر قواعد التعليمات البرمجية، لذلك تمت إضافة ميزات جديدة بشكل منفصل.