JavaScript Closures

From binaryoption
Jump to navigation Jump to search
Баннер1

```wiki

JavaScript Closures (الإغلاقات في JavaScript)

الإغلاقات (Closures) هي من أهم المفاهيم في لغة JavaScript، وغالبًا ما تُعتبر صعبة الفهم للمبتدئين. لكن فهمها ضروري لكتابة كود JavaScript فعال وقابل للصيانة. هذا المقال يهدف إلى شرح الإغلاقات بالتفصيل، مع أمثلة عملية لتوضيح كيفية عملها.

ما هي الإغلاقات؟

ببساطة، الإغلاق هو قدرة دالة على تذكر والوصول إلى نطاقها المعجمي (lexical scope) حتى بعد انتهاء تنفيذ الدالة الخارجية التي أنشأتها. دعنا نفكك هذا التعريف.

  • النطاق المعجمي (Lexical Scope): يشير إلى المكان الذي يتم فيه تعريف المتغيرات. في JavaScript، يتم تحديد النطاق بناءً على هيكل الكود. الدوال الداخلية يمكنها الوصول إلى المتغيرات المعرفة في الدوال الخارجية، ولكن ليس العكس. هذا مرتبط بـ النطاق (Scope) في JavaScript.
  • الدالة الخارجية (Outer Function): هي الدالة التي تحتوي على دالة داخلية.
  • الدالة الداخلية (Inner Function): هي الدالة المعرفة داخل دالة أخرى.

عندما يتم إنشاء دالة داخلية، فإنها تحتفظ بـ "إغلاق" على النطاق المحيط بها (النطاق الخاص بالدالة الخارجية). هذا يعني أن الدالة الداخلية يمكنها الوصول إلى المتغيرات المعرفة في الدالة الخارجية، حتى بعد انتهاء تنفيذ الدالة الخارجية.

مثال توضيحي

لنبدأ بمثال بسيط:

```javascript function outerFunction() {

 let outerVariable = 'مرحبا';
 function innerFunction() {
   console.log(outerVariable); // الوصول إلى outerVariable
 }
 return innerFunction;

}

let myClosure = outerFunction(); myClosure(); // سيطبع "مرحبا" ```

في هذا المثال:

1. `outerFunction` هي الدالة الخارجية. 2. `innerFunction` هي الدالة الداخلية. 3. `outerVariable` هو متغير معرف داخل `outerFunction`. 4. `innerFunction` تحتفظ بإغلاق على `outerVariable`.

حتى بعد انتهاء تنفيذ `outerFunction`، تحتفظ `myClosure` (التي هي في الواقع `innerFunction` التي تم إرجاعها) بإمكانية الوصول إلى `outerVariable`. هذا هو جوهر الإغلاق.

لماذا نستخدم الإغلاقات؟

الإغلاقات لها العديد من الاستخدامات المفيدة في JavaScript:

  • تغليف البيانات (Data Encapsulation): يمكن استخدام الإغلاقات لإنشاء متغيرات خاصة لا يمكن الوصول إليها مباشرة من الخارج. هذا يوفر مستوى من الأمان والتحكم في البيانات. يشبه هذا مفهوم التغليف في البرمجة الكائنية.
  • الحفاظ على الحالة (State Preservation): يمكن استخدام الإغلاقات للحفاظ على حالة معينة بين استدعاءات الدالة.
  • إنشاء دوال مصنع (Factory Functions): يمكن استخدام الإغلاقات لإنشاء دوال مصنع تقوم بإرجاع دوال أخرى مع بيانات محددة.
  • التعامل مع الأحداث (Event Handling): تستخدم الإغلاقات بشكل شائع في معالجة الأحداث للحفاظ على السياق الصحيح.

مثال على تغليف البيانات

```javascript function createCounter() {

 let count = 0;
 return {
   increment: function() {
     count++;
   },
   getCount: function() {
     return count;
   }
 };

}

let counter = createCounter(); counter.increment(); counter.increment(); console.log(counter.getCount()); // سيطبع 2

// محاولة الوصول إلى count مباشرة ستفشل // console.log(count); // خطأ: count غير معرف ```

في هذا المثال، `count` هو متغير خاص لا يمكن الوصول إليه مباشرة من الخارج. يمكن تعديله فقط من خلال الدالة `increment`، ويمكن الوصول إليه فقط من خلال الدالة `getCount`. هذا يوضح كيف يمكن استخدام الإغلاقات لتغليف البيانات وحمايتها.

مثال على الحفاظ على الحالة

```javascript function createTimer(delay) {

 let message;
 setTimeout(function() {
   console.log(message);
 }, delay);
 return function(msg) {
   message = msg;
 };

}

let timer = createTimer(2000); timer('تم الانتهاء!'); // تعيين الرسالة // بعد ثانيتين، سيتم طباعة "تم الانتهاء!" ```

هنا، الدالة الداخلية (داخل `setTimeout`) تحتفظ بإغلاق على `message`. حتى بعد انتهاء تنفيذ `createTimer`، يمكن للدالة الداخلية الوصول إلى `message` الذي تم تعيينه بواسطة الدالة التي تم إرجاعها.

الإغلاقات وكيفية عملها من الداخل

عندما يتم تعريف دالة، يتم إنشاء نطاق تنفيذي (execution scope) مرتبط بتلك الدالة. يتضمن هذا النطاق جميع المتغيرات المعرفة داخل الدالة، بالإضافة إلى المتغيرات المعرفة في النطاقات الخارجية التي يمكن الوصول إليها.

عندما يتم استدعاء دالة، يتم إنشاء كائن نطاق (scope object) يحتوي على جميع المتغيرات في النطاق الحالي. عندما تنتهي الدالة من التنفيذ، يتم تدمير كائن النطاق.

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

الإغلاقات في حلقات

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

```javascript for (var i = 0; i < 5; i++) {

 setTimeout(function() {
   console.log(i); // سيطبع 5 خمس مرات
 }, 1000);

} ```

في هذا المثال، سيتم طباعة 5 خمس مرات، بدلاً من 0، 1، 2، 3، 4. السبب هو أن المتغير `i` يتم تحديثه باستمرار داخل الحلقة. عندما يتم تنفيذ الدالة داخل `setTimeout`، تكون قيمة `i` هي القيمة الأخيرة التي تم تعيينها لها (وهي 5).

لحل هذه المشكلة، يمكننا استخدام `let` بدلاً من `var`:

```javascript for (let i = 0; i < 5; i++) {

 setTimeout(function() {
   console.log(i); // سيطبع 0، 1، 2، 3، 4
 }, 1000);

} ```

باستخدام `let`، يتم إنشاء متغير جديد `i` لكل تكرار من الحلقة. لذلك، تحتفظ كل دالة داخل `setTimeout` بإغلاق على قيمة `i` الخاصة بها.

بدلاً من ذلك، يمكننا استخدام دالة مصنع:

```javascript for (var i = 0; i < 5; i++) {

 (function(j) {
   setTimeout(function() {
     console.log(j); // سيطبع 0، 1، 2، 3، 4
   }, 1000);
 })(i);

} ```

في هذا المثال، نقوم بتمرير قيمة `i` كمعامل إلى دالة مصنع. تقوم الدالة المصنع بإنشاء متغير جديد `j` وتعيين قيمة `i` له. بهذه الطريقة، تحتفظ كل دالة داخل `setTimeout` بإغلاق على قيمة `j` الخاصة بها.

الإغلاقات والذاكرة

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

الإغلاقات في سياق الخيارات الثنائية

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

  • **إدارة البيانات التاريخية:** يمكن استخدام الإغلاقات لتغليف البيانات التاريخية للأسعار والحفاظ على الوصول إليها دون تعريضها للتعديل الخارجي.
  • **تنفيذ المؤشرات الفنية:** يمكن استخدام الإغلاقات لإنشاء مؤشرات فنية (مثل مؤشر المتوسط المتحرك، مؤشر القوة النسبية (RSI)) تحتفظ بحالة المؤشر عبر استدعاءات متعددة.
  • **استراتيجيات التداول التلقائي:** يمكن استخدام الإغلاقات لإنشاء استراتيجيات تداول تلقائية (مثل استراتيجية مارتينجال، استراتيجية دالالا، استراتيجية فيبوناتشي) تحتفظ ببيانات التداول وسجل الأداء.
  • **تحليل حجم التداول:** يمكن للإغلاقات المساعدة في الحفاظ على حالة تحليل حجم التداول، مما يسمح بتتبع الاتجاهات والأنماط بمرور الوقت.
  • **التحليل الفني:** يمكن استخدام الإغلاقات لتطبيق أنماط التحليل الفني المعقدة والحفاظ على حالتها.
  • **إدارة المخاطر:** يمكن استخدام الإغلاقات لإنشاء وحدات إدارة مخاطر تحتفظ بمعلومات حول حجم الصفقة ومستوى المخاطرة.
  • **تحديد الاتجاهات:** يمكن للإغلاقات المساعدة في تتبع الاتجاهات في السوق وتحديد نقاط الدخول والخروج المحتملة.
  • **تطوير الروبوتات:** في تطوير روبوتات تداول الخيارات الثنائية، يمكن الإغلاقات أن تساعد في الحفاظ على حالة الروبوت ومعلوماته.

الخلاصة

الإغلاقات هي مفهوم قوي في JavaScript يمكن استخدامه لحل العديد من المشاكل المعقدة. من خلال فهم كيفية عمل الإغلاقات، يمكنك كتابة كود JavaScript أكثر فعالية وقابلية للصيانة. تذكر أن الإغلاقات تسمح للدوال الداخلية بالوصول إلى المتغيرات في النطاقات الخارجية، حتى بعد انتهاء تنفيذ الدالة الخارجية. استخدم الإغلاقات بحذر، وتأكد من عدم الاحتفاظ بإغلاق على بيانات غير ضرورية لتجنب مشاكل الأداء.

روابط ذات صلة

```

ابدأ التداول الآن

سجّل في IQ Option (الحد الأدنى للإيداع 10 دولار) افتح حساباً في Pocket Option (الحد الأدنى للإيداع 5 دولار)

انضم إلى مجتمعنا

اشترك في قناة Telegram الخاصة بنا @strategybin لتصلك: ✓ إشارات تداول يومية ✓ تحليلات استراتيجية حصرية ✓ تنبيهات اتجاهات السوق ✓ مواد تعليمية للمبتدئين

Баннер