كيفية التقاط الإغلاقات للحالة
افهموا البيئة المعجمية للإغلاقات.
كيفية التقاط الإغلاقات للحالة درس مجاني في JavaScript Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في JavaScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة JavaScript Academy 4 دروس في المجموع.
ما هو Closure
إن Closure هو دالة مجمّعة مع مراجع إلى المتغيرات الموجودة في النطاق الذي عُرّفت فيه. وتحتفظ الدالة الداخلية بذكر تلك المتغيرات حتى بعد انتهاء الدالة الخارجية من التنفيذ.
function outer() {
const message = "hello";
function inner() {
console.log(message); // sees outer variable
}
inner();
}
outer(); // "hello"إرجاع الدالة الداخلية
تظهر الفكرة المهمة عند إرجاع الدالة الداخلية؛ إذ تظل قادرة على الوصول إلى المتغير الخارجي، رغم أن outer أنهت تنفيذها بالفعل.
function outer() {
const message = "remembered";
return function () {
console.log(message);
};
}
const fn = outer();
fn(); // "remembered"النطاق المعجمي
تعمل عمليات Closure بسبب النطاق المعجمي؛ إذ يمكن للدالة الوصول إلى المتغيرات المعرّفة في النطاقات التي تحيط بها فعليًا في الشيفرة المصدرية، لا في الموضع الذي تُستدعى فيه.
const x = 10;
function show() {
console.log(x); // resolves where defined
}
function run() {
const x = 99;
show(); // still logs 10, not 99
}
run();الالتقاط بالمرجع
يلتقط Closure المتغير نفسه، لا لقطة من قيمته. فإذا تغيّر المتغير لاحقًا، رأى Closure القيمة الجديدة.
function make() {
let count = 0;
const get = () => count;
count = 5; // changed after get defined
return get;
}
console.log(make()()); // 5ينشئ كل استدعاء نطاقًا جديدًا
ينشئ كل استدعاء للدالة الخارجية مجموعة جديدة من المتغيرات. ولا تشارك عمليات Closure الناتجة عن استدعاءات مختلفة الحالة نفسها.
function counter() {
let n = 0;
return () => ++n;
}
const a = counter();
const b = counter();
console.log(a(), a()); // 1 2
console.log(b()); // 1 (independent)الإغلاقات مع المعاملات
تلتقط الإغلاقات معاملات الدوال أيضًا. يتيح لكم ذلك إنشاء دوال متخصصة انطلاقًا من دالة عامة.
function adder(x) {
return (y) => x + y;
}
const add5 = adder(5);
console.log(add5(3)); // 8
console.log(add5(10)); // 15فخ الحلقة الشهير
خطأ مشهور: يؤدي استخدام var في حلقة إلى مشاركة متغير واحد بين جميع الإغلاقات. وعندما تُنفَّذ، تكون الحلقة قد انتهت، فتقرأ جميعها القيمة النهائية.
const fns = [];
for (var i = 0; i < 3; i++) {
fns.push(() => i);
}
console.log(fns[0](), fns[1](), fns[2]()); // 3 3 3إصلاح المشكلة باستخدام let
ينشئ let ارتباطًا جديدًا في كل تكرار، لذلك يلتقط كل إغلاق متغير i الخاص به. هذا هو الإصلاح الحديث.
const fns = [];
for (let i = 0; i < 3; i++) {
fns.push(() => i);
}
console.log(fns[0](), fns[1](), fns[2]()); // 0 1 2الإغلاقات تُبقي الذاكرة حيّة
ما دام الإغلاق موجودًا، لا يمكن جمع المتغيرات التي يلتقطها بواسطة جامع البيانات المهملة. لا يسبب ذلك مشكلة عادةً، لكنه قد يؤدي إلى تسرّبات إذا احتفظتم بالإغلاقات مدة أطول من اللازم.
function make() {
const big = new Array(3).fill("data");
return () => big.length;
}
const f = make();
console.log(f()); // 3 - big stays in memory via fالإغلاقات موجودة في كل مكان
تعتمد الاستدعاءات الراجعة ومعالجات الأحداث وsetTimeout وطرائق المصفوفات والوعود جميعًا على الإغلاقات لتذكّر السياق. أنتم تستخدمونها باستمرار، وغالبًا من دون أن تلاحظوا ذلك.
function greet(name) {
return () => console.log("Hi " + name);
}
[greet("Ada"), greet("Bob")].forEach((fn) => fn());
// Hi Ada
// Hi Bobفحص الحالة الملتقطة
تشترك الإغلاقات المتعددة الناتجة عن الاستدعاء نفسه في المتغيرات الملتقطة نفسها، لذلك يمكن لأحدها قراءة ما يكتبه آخر.
function pair() {
let value = 0;
return {
set: (v) => { value = v; },
get: () => value
};
}
const p = pair();
p.set(42);
console.log(p.get()); // 42تحقق سريع
كيفية التقاط الإغلاقات للحالة
مراجعة
الإغلاق هو دالة بالإضافة إلى مراجع للنطاق الذي عُرّفت فيه. وبفضل النطاق المعجمي، يتذكر الإغلاق المتغيرات الخارجية بعد عودة الدالة الخارجية، إذ يلتقطها بالمرجع لا بالقيمة. ينشئ كل استدعاء للدالة الخارجية نطاقًا مستقلًا؛ استخدموا let لتجنب فخ الحلقة. تُبقي الإغلاقات الذاكرة الملتقطة حيّة، وتدعم الاستدعاءات الراجعة في كل مكان.
الأسئلة الشائعة
هل درس «كيفية التقاط الإغلاقات للحالة» مجاني؟
نعم — نص درس «كيفية التقاط الإغلاقات للحالة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة JavaScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة JavaScript Academy 4 دروس في المجموع.
ماذا ستتعلم في «كيفية التقاط الإغلاقات للحالة»؟
افهموا البيئة المعجمية للإغلاقات. تتمرن على JavaScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ JavaScript Academy؟
لا تُشترط خبرة سابقة. JavaScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «كيفية التقاط الإغلاقات للحالة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس JavaScript Academy هذا؟
نعم. كل درس في JavaScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- كيفية التقاط الإغلاقات للحالة
- المتغيرات الخاصة باستخدام الإغلاقات
- نمط الوحدة (IIFE)
- دوال المُنشئ