JavaScript

JavaScript Function Closures
عمليات الإغلاق مع الدوال في لغة جافا سكريبت

في هذا الدرس سوف نتعرف علي الطريقة التي يمكننا من خلالها تحديد المنطقة التي نستطيع خلالها الوصول لعنصر معين

التاريخ

12 نوفمبر 2021

الدروس

146

المستوى

العامة

اللغة

انجليزي

المشاهدات

1459

المواضيع

24
الشروحات chevron_left JavaScript Function Closures chevron_left JavaScript

JavaScript Function Closures
عمليات الإغلاق مع الدوال في لغة جافا سكريبت

</> JavaScript Function Closures
عمليات الإغلاق مع الدوال في لغة جافا سكريبت

يمكن تحديد امكانية الوصول الي التغيرات بأحدي الطريقتين 

  • local : ونستطيع خلالها الوصول للمتغير بداخل اقواس التعريف التي تحتويه ولا يمكننا الوصول اليه خارجها 
  • global : وخلالها نستطيع الوصول الي المتغير في أي مكان بداخل البرنامج 

، Closure هو ببساطة دالة (function) تحتفظ بالحالة (state) المحيطة بها والتي تسمى (lexical environement). هذه الحالة تعبر عن المتغيرات الموجودة ضمن نطاق (scope) الدالة الخارجية (outer function) التي تحتوي هذه الدالة الداخلية (inner function).

في الصورة التالية 

 أولاً الدالة الخارجية تعرف متغيراً يسمى a وتسند له قيمة 5.
- الدالة الخارجية لديها دالة داخلية معرفة بداخلها.

- الدالة الداخلية تعرف متغيراً اسمه b وتسند له قيمة 10.

لا شيء جديد حتى الآن.

 الآن الدالة الداخلية تحاول طباعة المتغيرين a و b عن طريق العبارة console.log.

السؤال يأتي الآن، كيف للدالة الداخلية أن تعرف عن المتغير a الذي لم تقم بتعريفه بنفسها؟ هذا هو بالضبط ما يسمى Closure.

إذاً، مرة أخرى. Closure هو دالة تحتفظ بالحالة المحيطة بها (متغيرات) والتي تكون موجودة ضمن نطاق الدالة الخارجية.

</> Global Variables

يمكن للدالة الوصول الي المتغيرات المنشئه بداخلها 

1. يمكن استخدام المتغيرات العالمية في أي مكان في برنامجنا . 

2. يمكن استخدام هذا المتغير العالمي في مختلف ملفات header المستخدم . ويمكن أيضا تغيير المتغيرات العالمية برمجيا.

3. عمر أو نطاق المتغير المحلي هو فقط ضمن إجراء أو كتلة في حين أن نطاق المتغير العالمي هو طوال البرنامج.

4. في حين يمكن إجراء تعديلات في متغير عالمي من أي مكان، فإنه لا يمكن القيام به مع المتغيرات المحلية.

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

Example
function myFunction() {
  let a = 4;
  return a * a;
}

ويمكنها ايضا الوصول المتغيرات التي تم انشائها خارجها وفي هذه الحالة يكون المتغير من النوع global

<script>
let a = 4;
myFunction();

function myFunction() {
  document.getElementById("demo").innerHTML = a * a;
}
Example
function myFunction() {
  a = 4;
}

في صفحات الويب تنتمي المتغيرات التي من النوع global الي window object 

Global variables : يمكننا الوصول اليها واستخدامها او تغيير قيمتها من اي مكان بداخل الكود

local variables : لا يمكننا الوصول اليها من اي مكان خارج الدالة التي تم انشائه خلالها

  • اي متغير نقوم بأنشائه باستخدام الانواع التالية (var او let او const ) يكون بشكل تلقائي من النوع global واي نوع اخر من البيانات يكون من النوع local 

</> Variable Lifetime

يبدأ عمر المتغير في لغة جافا سكريبت عندما يتم الإعلان عنه. يتم حذف متغيرات الوظيفة function (المحلية) عند انتهاء تنفيذها. في متصفح الويب ، يتم حذف المتغيرات العامة عند إغلاق نافذة المتصفح (أو علامة التبويب).
  • Global variables : تظل موجودة بداخل البرنامج حتي تنتقل من الصفحة الي صفحة اخري او تقوم بغلق نافذة المتصفح 
  • Local variables : لا يتم انشائها الا حينما تقوم بأستدعاء الدالة وبمجرد انتهاء تنفيذ الدالة يتم اهمال هذا المتغير مره اخري

</> A Counter Dilemma

اذا كنت بحاجه الي  استخدام متغير لحساب شيء ما ، وتريد أن يكون هذا المتغير متاحًا لجميع الدوال الأخرى ففي هذه الحالة انت بحاجة الي استخدام متغير من النوع global ودالة تقوم بزيادة قيمة هذا المتغير 

/* Initiate counter */
let counter = 0;

/*Function to increment counter */
function add() {
  counter += 1;
}

/* Call add() 3 times */
add();
add();
add();

/* The counter should now be 3 */

يوجد مشكلة ما تنتج عندما نقوم بأستخدام الحل السابق وهي ان المتغير الذي قمنا بأنشائه هو من النوع global ففي هذه الحالة يمكنن تغيير قيمته من اي مكان في البرنامج بدون استدعاء الدالة ( )`add لذلك من الافضل جعل المتغير من النوع local حتي نستطيع التحكم في هذه النقطة ولكن في هذه الحالة سوف يتم اعادة تعيين قيمة المتغير في كل مره نقوم في بأستدعاء الدالة

/* Function to increment counter */
function add() {
  let counter = 0;
  counter += 1;
  return counter;
}

/* Call add() 3 times */
add();
add();
add();

/* The counter should now be 3. But it is 1. */

 يرجي العلم انه لا نستطيع ان نقوم بأنشاء متغيرين بنفس الاسم احدهم local والاخر global 

</> JavaScript Nested Functions

في لغة الجافاسكريبت تستيطع الدوال الوصول الي المتغيرات التي تم أنشائها في الاسطر التي تسبقها وكذلك الدوال المتداخلة تستطيع ايضا والمثال التالي تستطيع الدالة ( )plus الوصول الي المتغير counter في الدالة الفرعية parent function التي تتواجد بداخل دالة اخري 

- وبهذه الطريقة يمكننا حل المشكلة السابقة الخاصة بالمتغير counter 

Example
function add() {
  let counter = 0;
  function plus() {counter += 1;}
  plus();   
  return counter;
}

</> JavaScript Closures

  •  يتم ارجاع قيمة الدالة ( )add في حالة الاستدعاء الذاتي 
  • دالة الاستدعاء الذاتي بتم تنفيذها مره واحده فقط وتقوم خلالها بأعادة تعيين قيمة المتغير الي صفر 
  • يمكننا الوصول الي المتغير بداخل الدالة الفرعية الموجودة بداخل دالة ( )add علي الرغم من انشائه خارجها 
Example
const add = (function () {
  let counter = 0;
  return function () {counter += 1; return counter}
})();

add();
add();
add();

/* the counter is now 3 */

ال closure هو عبارة عن دالة لها حق الوصول الي النطاق الأصلي حتي بعد اغلاق الدالة الرئيسية 

</> Local variables in JavaScript function
المتغيرات المحلية مع الدوال في لغة جافا سكريبت

تستخدم المتغيرات variables مع الدوال functions ويمكن اجراء اي عمليات علي المتغيرات بداخل ال function ويمكنك استرجاع قيم المتغيرات بداخل ال return statement.


في لغة البرمجة نوعين من المتغيرات variables:

  • local variables : يُعرّف المتغير المحلي بأنه نوع من المتغير المُعرّف داخل (block) برمجي أو داخل الإجراءات الفرعية مثل جمل (for و if)، ويمكن استخدامها فقط داخل كود الإجراء الفرعي أو (block) الذي تم تعريف المتغير فيه، ويظل المتغير المحلي موجود حتى يتم تنفيذ (block) الدالة، بعد ذلك، سيتم تدميره تلقائيًا. 
  • global variables : المتغير العالمي في البرنامج هو متغير محدد خارج الإجراء الفرعي أو الدالة، له نطاق عالمي يعني أنه يحتفظ بقيمته طوال عمر البرنامج، بالتالي، يمكن الوصول إليها في جميع أنحاء البرنامج من خلال أي دالة محددة داخل البرنامج، ما لم تكن مظللة. في المثال أدناه يعتبر ‘a’ و ‘b’ متغيران عالميان.


Local Variable

متغير معرف داخل الدالة لا يمكنك استخدامة خارج الدالة.

function myFunction() {
  var username = "Ahmed";
  document.write(  typeof username + "<br>");
  document.write(  username + "<br>");
}
myFunction();
document.write("Out function <br>");
document.write(typeof username);
Global Variable

متغير معرف خارج الدالة يمكنك استخدامة خارج وداخل الدالة.

var username = "Ahmed";
function myFunction() {
  document.write(  typeof username + "<br>");
  document.write(  username + "<br>");
}
myFunction();
document.write("Out function <br>");
document.write(typeof username);
لا يمكن استخدام ال local variables التي تعرف داخل ال function خارج حدود ال function فقط بداخلها

</> Nested functions and closures in JavaScript
دالة متداخلة في لغة جافا سكريبت

يمكننا وضع دالة ليتم تنفيذها بداخل دالة أخري

  • تسمي الدالة الداخلية التي توضع بداخل دالة أخري ب inner function.
  • الدالة الداخلية inner function يمكن الوصول اليها خلال اقواس الدالة الخارجية outer function فقط ولا نستطيع الوصول اليها من خارج هذه الأقواس.
  • تسمي الدالة الخارجية التي يتم وضع دالة بداخلها بالدالة الخارجية outer function.
Nested functions

دالة معرفة ومتداخلة داخل دالة اخري.

function parent(a, b) {
  function child(x) {
    return x * x;
  }
  return child(a) + child(b);
}
document.write(parent(5,10));
document.write("<br>");
document.write(parent(3,6));
معلومات تهمك
  • لا تنسى تقييم الدروس لكي نُحدّث المُحتوى باستمرار حتى ينال إعجابك.
  • لا تنسى مشاركة الموقع مع أصدقاءك حتى تعمّ الفائدة وتكون سبب في نفعهم.
مشاركة
0
0
0
0
عدد المشاركات
هل هذه المعلومات نالت إعجابك ؟
0
0
عدد التقييمات

لديك استفسار ؟

يسعدنا كثيرا مساعدتك في استيعاب افضل للأمور, فلا تترد مطلقا في الاتصال بنا في حال كانت لديك اية اسئله او استفسارات.