1. نطاق المتغيرات
لفهم عمليات الإغلاق ، يجب عليك أولاً فهم النطاق المتغير الخاص لـ JavaScript.
لا يوجد سوى نوعين من نطاقات المتغيرات: المتغيرات العالمية والمتغيرات المحلية.
الميزة الخاصة للغة JavaScript هي أنه يمكن قراءة المتغيرات العالمية مباشرة داخل الوظائف.
var n = 999 ؛ دالة f1 () {Alert (n) ؛ } f1 () ؛ // 999من ناحية أخرى ، لا تتم قراءة المتغيرات المحلية داخل الوظيفة بشكل طبيعي خارج الوظيفة.
الدالة f1 () {var n = 999 ؛ } تنبيه (n) ؛ // خطأهناك مكان يجب ملاحظته هنا. عند إعلان المتغيرات داخليًا ، يجب عليك استخدام أمر VAR. إذا لم يكن الأمر كذلك ، فأنت تعلن بالفعل متغيرًا عالميًا!
الدالة f1 () {n = 999 ؛ } f1 () ؛ تنبيه (ن) ؛ // 9992. كيف تقرأ المتغيرات المحلية من الخارج؟
لأسباب مختلفة ، نحتاج أحيانًا إلى الحصول على متغيرات محلية داخل الوظيفة. ومع ذلك ، كما ذكرنا سابقًا ، في ظل الظروف العادية ، لا يمكن القيام بذلك ولا يمكن تحقيقه إلا من خلال الحلول.
وهذا هو تحديد وظيفة أخرى داخل الوظيفة.
الدالة f1 () {var n = 999 ؛ الدالة f2 () {Alert (n) ؛ // 999}}في الكود أعلاه ، يتم تضمين الوظيفة F2 داخل الوظيفة F1 ، وجميع المتغيرات المحلية داخل F1 مرئية لـ F2. لكن العكس غير ممكن. المتغيرات المحلية داخل F2 غير مرئية لـ F1. هذا هو بنية "نطاق السلسلة" الفريدة للغة JavaScript. ستبدو الكائنات الفرعية مستوى لأعلى حسب مستوى متغيرات جميع الكائنات الأصل. لذلك ، فإن جميع متغيرات الكائن الأصل مرئي للكائن الطفل ، وإلا فإنه غير صحيح.
نظرًا لأن F2 يمكنه قراءة المتغيرات المحلية في F1 ، طالما يتم استخدام F2 كقيمة الإرجاع ، ألا يمكننا قراءة متغيراتها الداخلية خارج F1؟
الدالة f1 () {var n = 999 ؛ الدالة f2 () {Alert (n) ؛ } return f2 ؛ } var result = f1 () ؛ نتيجة()؛ // 9993. مفهوم الإغلاق
وظيفة F2 في القسم السابق من الرمز هي الإغلاق.
تعريف "الإغلاق" في مختلف المستندات المهنية مجردة للغاية ويصعب فهمه. أفهم أن الإغلاق هو وظيفة يمكنها قراءة المتغيرات داخل وظائف أخرى.
نظرًا لأنه في لغة JavaScript ، يمكن فقط للوظائف الفرعية داخل الوظائف قراءة المتغيرات المحلية ، يمكن فهم عمليات الإغلاق ببساطة على أنها "وظائف محددة داخل وظيفة".
لذلك ، في جوهرها ، الإغلاق هو جسر يربط داخل وخارج الوظيفة.
4. الغرض من الإغلاق
يمكن استخدام عمليات الإغلاق في العديد من الأماكن. إنه له أكبر استخدامات ، أحدهما هو أن المتغيرات الموجودة داخل الوظيفة يمكن قراءة كما ذكر أعلاه ، والآخر هو أن قيم هذه المتغيرات يتم الاحتفاظ بها دائمًا في الذاكرة.
كيف تفهم هذه الجملة؟ يرجى الاطلاع على الرمز أدناه.
الدالة f1 () {var n = 999 ؛ nadd = function () {n+= 1} function f2 () {Alert (n) ؛ } return f2 ؛ } var result = f1 () ؛ نتيجة()؛ // 999 NADD () ؛ نتيجة()؛ // 1000في هذا الرمز ، النتيجة هي في الواقع وظيفة الإغلاق F2. يتم تشغيله مرتين في المجموع ، والقيمة الأولى هي 999 والقيمة الثانية هي 1000. وهذا يثبت أن المتغير المحلي N في الوظيفة F1 قد تم الاحتفاظ به في الذاكرة ولم يتم مسحه تلقائيًا بعد استدعاء F1.
لماذا هذا يحدث؟ والسبب هو أن F1 هو الدالة الأصل لـ F2 ، ويتم تعيين F2 لمتغير عالمي ، والذي يتسبب في أن يكون F2 دائمًا في الذاكرة ، ويعتمد وجود F2 على F1. لذلك ، يكون F1 دائمًا في الذاكرة ولن يتم إعادة تدويره بواسطة آلية جمع القمامة بعد الانتهاء من المكالمة.
هناك نقطة أخرى جديرة بالملاحظة في هذا الرمز وهي أن السطر "nadd = function () {n+= 1}" يستخدم لأول مرة قبل NADD ، لذلك NADD هو متغير عالمي ، وليس متغيرًا محليًا. ثانياً ، قيمة NADD هي وظيفة مجهولة ، وهذه الوظيفة المجهولة نفسها هي أيضًا إغلاق ، لذلك فإن NADD تعادل مراسلة ، والتي يمكن أن تعمل على المتغيرات المحلية داخل الوظيفة خارج الوظيفة.
5. ملاحظات حول استخدام الإغلاق
1) نظرًا لأن عمليات الإغلاق سوف تتسبب في تخزين جميع المتغيرات في الوظيفة في الذاكرة ، ولا يمكن إساءة استخدام استهلاك الذاكرة ، ولا يمكن إساءة استخدامها ، وإلا فإنه سيؤدي إلى مشاكل في أداء صفحة الويب وقد يؤدي إلى تسرب الذاكرة في IE. الحل هو حذف جميع المتغيرات المحلية التي لا تستخدم قبل الخروج من الوظيفة.
2) سيغير الإغلاق قيمة المتغير داخل وظيفة الأصل خارج وظيفة الأصل. لذلك ، إذا كنت تستخدم وظيفة الأصل ككائن ، فاستخدم الإغلاق كطريقة عامة له ، واستخدم المتغير الداخلي كخاصية خاصة به ، فاحرص على عدم تغيير قيمة المتغير الداخلي لوظيفة الأصل في الإرادة.