Programming Basics SQL HTML CSS JavaScript Python C++ Java JavaFX Swing Problem Solving English English Conversations Computer Fundamentals Learn Typing

جافاسكربتالرفع

  • مفهوم الرفع
  • رفع نطاق المتغيرات
  • رفع نطاق الدوال

مفهوم الرفع

الرفع ( Hoisting ) يقصد به جعل الوصول إلى المتغيرات و الدوال ممكناً من خارج المكان الذي تم تعريفها فيه.

قد يبدو لك هذا الأمر غريباً بعض الشيء و لكنك ستفهم كيف أن ذلك متاحاً في جافاسكربت عندما تفهم كيف يتعامل مفسر الكود معها.

الرفع في جافاسكرب يتم بشكل تلقائي و حصري على المتغيرات التي لم يتم تحديد نوعها و الدوال.

رفع نطاق المتغيرات

عند تعريف المتغير باستخدام الأسلوب التلقائي، أي عند تعريفه بدون استخدام إحدى الكلمات المفتاحية var أو let أو const فإنه يكون بمثابة متغير عام ( Global ) يمكن الوصول له من أي مكان كان. و لكن في حال تم إعادة تعريف هذا المتغير بواسطة الكلمة var فإنه سيتم رفع نطاقه إلى المكان الذي تم تعريفه فيه فقط.

لا يمكن إعادة تعريف المتغير باستعمال let أو const لأن هذه الكلمات يمكن استعمالها فقط في لحظة تعريف المتغير.


رفع نطاق المتغير إلى الأعلى

في المثال التالي قمنا بتعريف دالة إسمها demo تحتوي على الجملة الشرطية if و بداخلها قمنا بتعريف متغير إسمه x.

هنا على الرغم من أن المتغير x قد تم تعريفه بداخل الجملة الشرطية if إلا أننا استطعنا الوصول إليه من خارج الجملة الشرطية و من خارج الدالة demo() لأنه يعتبر بمثابة متغير عام.

مثال

// demo هنا قمنا بتعريف دالة إسمها
function demo() {
// true هنا قمنا بوضع جملة شرط و ستتنفذ لأن جواب الشرط فيها يساوي
if (true) {
// و قيمته 10 x هنا قمنا بتعريف متغير عام إسمه
x = 10;
// x هنا قمنا بطباعة قيمة المتغير
document.write('x inside the if statement scope = ' + x + '<br>');
}
// من جديد x هنا قمنا بطباعة قيمة المتغير
document.write('x inside the function scope = ' + x + '<br>');
}
// حتى تتنفذ demo() هنا قمنا باستدعاء الدالة
demo();
// demo() الذي سبق و تم تعريفه في الدالة x هنا قمنا بطباعة قيمة المتغير
document.write('x inside the global scope = ' + x);
// demo هنا قمنا بتعريف دالة إسمها function demo() { // true هنا قمنا بوضع جملة شرط و ستتنفذ لأن جواب الشرط فيها يساوي if (true) { // و قيمته 10 x هنا قمنا بتعريف متغير عام إسمه x = 10; // x هنا قمنا بطباعة قيمة المتغير document.write('x inside the if statement scope = ' + x + '<br>'); } // من جديد x هنا قمنا بطباعة قيمة المتغير document.write('x inside the function scope = ' + x + '<br>'); } // حتى تتنفذ demo() هنا قمنا باستدعاء الدالة demo(); // demo() الذي سبق و تم تعريفه في الدالة x هنا قمنا بطباعة قيمة المتغير document.write('x inside the global scope = ' + x);

النتيجة

x inside the if statement scope = 10
x inside the function scope = 10
x inside the global scope = 10
جرب الكود

إعادة تحديد نطاق المتغير

فيما يلي سنقوم بإعادة المثال و لكننا هذه المرة سنقوم بإعادة تحديد نطاق المتغير x بعد تعريفه ليصبح بالإمكان الوصول إليه من داخل الدالة demo() فقط.

الفرق بين هذا المثال و المثال السابق أنه عند محاولة الوصول إلى المتغير x من خارج الدالة demo() فإنه سيظهر لنا الخطأ Uncaught ReferenceError و الذي يعني أنه لم يتم إيجاد المتغير.

مثال

// demo هنا قمنا بتعريف دالة إسمها
function demo() {
// true هنا قمنا بوضع جملة شرط و ستتنفذ لأن جواب الشرط فيها يساوي
if (true) {
// و قيمته 10 x هنا قمنا بتعريف متغير عام إسمه
x = 10;
// من جديد مع عدم تغيير قيمته الحالية x هنا قمنا بتعريف المتغير
var x;
// و لاحظ أنها بقيت 10 x هنا قمنا بطباعة قيمة المتغير
document.write('x inside the if statement scope = ' + x + '<br>');
}
// من جديد x هنا قمنا بطباعة قيمة المتغير
document.write('x inside the function scope = ' + x + '<br>');
}
// حتى تتنفذ demo() هنا قمنا باستدعاء الدالة
demo();
// demo() الذي سبق و تم تعريفه في الدالة x هنا حاولنا طباعة قيمة المتغير
// يمكن الوصول إليه من داخل الدالة فقط x تنفيذ هذا الأمر سيسبب مشكلة لأن المتغير
document.write('x inside the global scope = ' + x);
// demo هنا قمنا بتعريف دالة إسمها function demo() { // true هنا قمنا بوضع جملة شرط و ستتنفذ لأن جواب الشرط فيها يساوي if (true) { // و قيمته 10 x هنا قمنا بتعريف متغير عام إسمه x = 10; // من جديد مع عدم تغيير قيمته الحالية x هنا قمنا بتعريف المتغير var x; // و لاحظ أنها بقيت 10 x هنا قمنا بطباعة قيمة المتغير document.write('x inside the if statement scope = ' + x + '<br>'); } // من جديد x هنا قمنا بطباعة قيمة المتغير document.write('x inside the function scope = ' + x + '<br>'); } // حتى تتنفذ demo() هنا قمنا باستدعاء الدالة demo(); // demo() الذي سبق و تم تعريفه في الدالة x هنا حاولنا طباعة قيمة المتغير // يمكن الوصول إليه من داخل الدالة فقط x تنفيذ هذا الأمر سيسبب مشكلة لأن المتغير document.write('x inside the global scope = ' + x);

النتيجة في الصفحة

x inside the if statement scope = 10
x inside the function scope = 10

الخطأ في الكونسول

Uncaught ReferenceError: x is not defined
جرب الكود

رفع نطاق الدوال

الدوال في جافاسكربت يتم رفعها بشكل تلقائي لأعلى نطاق مما يعني أنه بالإمكان استدعاء الدالة قبل أن يتم تعريفها.

الرفع التلقائي للدوال سببه أن مفسر الكود سيقوم بالبحث عن الدالة عندما يتم استدعائها و لهذا فإنه لا يهتم أين هي موجودة في الأصل.


في المثال التالي قمنا باستدعاء إسمها demo() قبل أن نقوم بتعريفها.

مثال

// حتى تتنفذ demo() هنا قمنا باستدعاء الدالة
demo();
// demo هنا قمنا بتعريف الدالة
function demo() {
document.write('demo is called');
}
// حتى تتنفذ demo() هنا قمنا باستدعاء الدالة demo(); // demo هنا قمنا بتعريف الدالة function demo() { document.write('demo is called'); }

النتيجة

demo is called
جرب الكود

في الدرس التالي ستتعلم كيف تستطيع إعلام مفسر جافاسكربت أنك تريد إيقاف استعمال أسلوب الرفع التلقائي مما يجعلك مجبر على تعريف الأشياء قبل أن تتمكن من استعمالها.