JS / الرفع

الرفع

مفهوم الرفع

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

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

JS - الرفع


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

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

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

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


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

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

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

مثال

خد الكواد نسخ واضغط هنا جرب الكود 📋
<!DOCTYPE html>
<html>
<body>
    <script>
		// 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);
    </script>
</body>
</html>

النتيجة

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 و الذي يعني أنه لم يتم إيجاد المتغير.

مثال

خد الكواد نسخ واضغط هنا جرب الكود 📋
<!DOCTYPE html>
<html>
<body>
    <script>
		// 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);
    </script>
</body>
</html>

// 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() قبل أن نقوم بتعريفها.

مثال

خد الكواد نسخ واضغط هنا جرب الكود 📋
<!DOCTYPE html>
<html>
<body>
    <script>
		// حتى تتنفذ demo() هنا قمنا باستدعاء الدالة
		demo();

		// demo هنا قمنا بتعريف الدالة
		function demo() {
			document.write('demo is called');
		}
    </script>
</body>
</html>

النتيجة

demo is called

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

إرسال تعليق

أحدث أقدم

نموذج الاتصال