الإغلاق في جافا سكريبت

الإغلاق في جافا سكريبت

تشرح هذه المقالة مفهوم الإغلاق في جافا سكريبت۔

YouTube Video

الإغلاق في جافا سكريبت

في جافا سكريبت، يُعتبر 'الإغلاق' أحد المفاهيم الهامة والقوية للغاية۔ من خلال فهم الإغلاق، يمكنك اكتساب معرفة مفيدة في العديد من المواقف، مثل سلوك ونطاق الوظائف بالإضافة إلى المعالجة غير المتزامنة ومعالجة الأحداث في جافا سكريبت۔ هنا، سوف نشرح بالتفصيل كل شيء بدءًا من التعريف الأساسي للإغلاقات إلى الأمثلة الملموسة وتطبيقاتها۔

ما هو الإغلاق؟

يشير الإغلاق إلى الآلية التي تتيح للوظيفة الوصول إلى المتغيرات ضمن نطاق إنشائها حتى عند استدعائها خارج هذا النطاق۔ من خلال استخدام الإغلاق، يمكن للوظائف الاستمرار في 'تذكر' المتغيرات الخارجية۔

تتكون الإغلاقات من العنصرين التاليين۔

  1. تعريف الوظيفة (الوظيفة نفسها)

  2. النطاق المحيط بتعريف الوظيفة (المتغيرات والوظائف الأخرى خارج الوظيفة نفسها)

الإغلاق ممكن في جافا سكريبت لأن الوظائف لديها القدرة على الوصول إلى المتغيرات داخل النطاق الذي تم إنشاؤها فيه۔

مثال أساسي

أولاً، لنُلق نظرة على مثال أساسي للإغلاق۔ في الكود التالي، تقوم الوظيفة outerFunction بإرجاع وظيفة تسمى innerFunction۔ النقطة المهمة هي أن innerFunction يمكنها الوصول إلى المتغير count الذي تم تعريفه داخل نطاق outerFunction۔

 1function outerFunction() {
 2    let count = 0;
 3
 4    function innerFunction() {
 5        count++;
 6        console.log(`Current count: ${count}`);
 7    }
 8
 9    return innerFunction;
10}
11
12const counter = outerFunction();
13counter(); // Current count: 1
14counter(); // Current count: 2
15counter(); // Current count: 3

كيف يعمل الإغلاق

كما يظهر في المثال أعلاه، يتم الاحتفاظ بـ count بواسطة innerFunction حتى بعد تنفيذ outerFunction۔ يمكن لـ innerFunction الاستمرار في الوصول إلى نطاق outerFunction، وبالتالي يتم تحديث count داخل innerFunction۔ هذه هي الآلية الأساسية للإغلاق۔

إن innerFunction هي الوظيفة المخصصة للمتغير counter، ويمكننا ملاحظة أن حالة count محفوظة حتى بعد انتهاء تنفيذ outerFunction۔ وذلك لأن جافا سكريبت تستمر في 'تذكر' النطاق في وقت تعريف الوظيفة۔

التطبيق: الإغلاق كمتغيرات خاصة

يمكن استخدام الإغلاقات مثل 'المتغيرات الخاصة' في البرمجة الكائنية التوجه۔ عادةً، في JavaScript، يمكن الوصول إلى خصائص الكائنات مباشرةً من الخارج، ولكن باستخدام الإغلاقات يمكن منع التلاعب المباشر بالمتغيرات داخل نطاق الوظيفة من الخارج۔

في المثال التالي، تستخدم وظيفة createCounter إغلاقًا لإنشاء عدّاد وتُرجع عدّادًا يحتوي على متغير خاص count۔

 1function createCounter() {
 2    let count = 0;
 3
 4    return {
 5        increment: function() {
 6            count++;
 7            console.log(`Count: ${count}`);
 8        },
 9        decrement: function() {
10            count--;
11            console.log(`Count: ${count}`);
12        },
13        getCount: function() {
14            return count;
15        }
16    };
17}
18
19const myCounter = createCounter();
20myCounter.increment(); // Count: 1
21myCounter.increment(); // Count: 2
22myCounter.decrement(); // Count: 1
23console.log(myCounter.getCount()); // 1

في هذا المثال، يكون count داخل نطاق وظيفة createCounter، لذلك لا يمكن الوصول إليه مباشرةً من الخارج۔ ومع ذلك، يمكن التلاعب به من خلال الطريقتين increment و decrement۔ بهذه الطريقة، باستخدام الإغلاقات، يمكنك إدخال مفهوم المتغيرات الخاصة في JavaScript۔

أمثلة عملية على الإغلاقات

الدمج مع دوال الاستدعاء

غالبًا ما تُستخدم الإغلاقات بالدمج مع دوال الاستدعاء لإدارة المعالجة غير المتزامنة۔ على سبيل المثال، دعنا ننظر في مثال باستخدام مؤقّت۔

 1function startTimer(duration) {
 2    let timeLeft = duration;
 3
 4    function countdown() {
 5        console.log(`Time left: ${timeLeft} seconds`);
 6        timeLeft--;
 7
 8        if (timeLeft >= 0) {
 9            setTimeout(countdown, 1000);
10        }
11    }
12
13    countdown();
14}
15
16startTimer(5);
17// Time left: 5 seconds
18// Time left: 4 seconds
19// Time left: 3 seconds
20// Time left: 2 seconds
21// Time left: 1 second
22// Time left: 0 seconds

في هذا المثال، تصل وظيفة countdown إلى المتغير timeLeft داخل نطاق startTimer۔ بهذه الطريقة، تكون الإغلاقات مفيدة جدًا للمعالجة غير المتزامنة مثل المؤقتات، لأنها تحافظ على حالة المتغيرات بمرور الوقت۔

معالجات الأحداث

تكون الإغلاقات مفيدة أيضًا عند إعداد معالجات الأحداث۔ في المثال التالي، يتم استخدام إغلاق لتسجيل عدد مرات النقر على الزر۔

 1function setupClickCounter(buttonId) {
 2    let clickCount = 0;
 3
 4    const button = document.getElementById(buttonId);
 5    button.addEventListener('click', function() {
 6        clickCount++;
 7        console.log(`Button clicked ${clickCount} times`);
 8    });
 9}
10
11setupClickCounter('myButton');

في هذه الحالة، يزيد clickCount مع كل نقرة ويتم الاحتفاظ بقيمته۔ باستخدام الإغلاقات، يمكنك تعيين عداد مستقل لكل زر۔

الخاتمة

الإغلاقات هي مفهوم يرمز إلى مرونة وقوة JavaScript۔ تحتفظ الإغلاقات بالمتغيرات داخل نطاق الوظيفة وتسمح بالعمليات عليها من خلال دوال يمكن الوصول إليها من الخارج۔ من خلال فهم واستغلال هذه الآلية، يمكنك اكتساب تقنيات أكثر تقدمًا في كتابة أكواد JavaScript۔

تُطبق الإغلاقات في مواقف متعددة، بدءًا من معالجة الأحداث والمعالجة غير المتزامنة إلى حتى التمثيلات الوهمية للبرمجة الكائنية التوجه۔

يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔

YouTube Video