1. ما هو الإغلاق
الإغلاق هو وظيفة لديها إذن للوصول إلى المتغيرات في نطاق وظيفة آخر.
ببساطة ، يسمح JavaScript باستخدام الوظائف الداخلية - أي تعريفات الوظائف وتعبيرات الوظائف موجودة في جسم وظيفة وظيفة أخرى. علاوة على ذلك ، يمكن لهذه الوظائف الداخلية الوصول إلى جميع المتغيرات المحلية والمعلمات والوظائف الداخلية الأخرى المعلنة في الوظيفة الخارجية حيث يقيمون. عندما يتم استدعاء إحدى هذه الوظائف الداخلية خارج الوظيفة الخارجية التي تحتوي عليها ، يتم تشكيل إغلاق.
2. نطاق المتغيرات
لفهم عمليات الإغلاق ، يجب أولاً فهم نطاق المتغيرات.
لا يوجد سوى نوعين من نطاقات المتغيرات: المتغيرات العالمية والمتغيرات المحلية.
الميزة الخاصة للغة JavaScript هي أنه يمكن قراءة المتغيرات العالمية مباشرة داخل الوظائف.
يمكن الوصول إلى متغيرات الوظائف الخارجية في الوظيفة الداخلية لأن سلسلة نطاق الوظيفة الداخلية تحتوي على نطاق الوظيفة الخارجية ؛
يمكن أيضًا فهمه على النحو التالي: يشع نطاق عمل الوظيفة الداخلية إلى نطاق عمل الوظيفة الخارجية ؛
var n = 999 ؛ function f1 () {Alert (n) ؛} f1 () ؛ // 999من ناحية أخرى ، لا تتم قراءة المتغيرات المحلية داخل الوظيفة بشكل طبيعي خارج الوظيفة.
الدالة f1 () {var n = 999 ؛} التنبيه (n) ؛ // خطأهناك مكان يجب ملاحظته هنا. عند إعلان المتغيرات داخليًا ، يجب عليك استخدام أمر VAR. إذا لم يكن الأمر كذلك ، فأنت تعلن بالفعل متغيرًا عالميًا!
الدالة f1 () {n = 999 ؛} f1 () ؛ Alert (n) ؛ // 9993. عدة طرق للكتابة واستخدام الإغلاق
3.1. أضف بعض الخصائص إلى الوظيفة
دائرة الدالة (r) {this.r = r ؛ } circle.pi = 3.14159 ؛ circle.prototype.area = function () {return circle.pi * this.r * this.r ؛ } var c = New Dircle (1.0) ؛ تنبيه (c.area ()) ؛ //3.141593.2. إعلان متغير وتعيين دالة للمتغير كقيمة.
var circle = function () {var obj = new Object () ؛ OBJ.PI = 3.14159 ؛ obj.area = function (r) {return this.pi * r * r ؛ } إرجاع OBJ ؛ } var c = New Circle () ؛ تنبيه (c.area (1.0)) ؛ //3.141593.3. يتم استخدام هذه الطريقة بشكل متكرر أكثر وهي الأكثر ملاءمة. var obj = {} هو إعلان كائن فارغ
var circle = {"pi": 3.14159 ، "area": function (r) {return this.pi * r * r ؛ }} ؛ التنبيه (Circle.area (1.0)) ؛ // 3.141594. الوظيفة الرئيسية للإغلاق
يمكن استخدام عمليات الإغلاق في العديد من الأماكن. له أكبر استخدامات: أحدهما هو أن المتغيرات الموجودة داخل الوظيفة يمكن قراءة كما ذكر أعلاه ، والآخر هو أن قيم هذه المتغيرات يتم الاحتفاظ بها دائمًا في الذاكرة.
4.1. كيف تقرأ المتغيرات المحلية من الخارج؟
لأسباب مختلفة ، نحتاج أحيانًا إلى الحصول على متغيرات محلية داخل الوظيفة. ومع ذلك ، كما ذكرنا سابقًا ، في ظل الظروف العادية ، لا يمكن القيام بذلك ولا يمكن تحقيقه إلا من خلال الحلول.
وهذا هو تحديد وظيفة أخرى داخل الوظيفة.
الدالة 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 () ؛ result () ؛ // 9994.2. كيف تحفظ دائمًا قيمة المتغير في الذاكرة؟
الدالة f1 () {var n = 999 ؛ nadd = function () {n+= 1} function f2 () {Alert (n) ؛ } return f2 ؛} var result = f1 () ؛ result () ؛ // 999nadd () ؛ result () ؛ // 1000في هذا الرمز ، النتيجة هي في الواقع وظيفة الإغلاق F2. يتم تشغيله مرتين في المجموع ، والقيمة الأولى هي 999 والقيمة الثانية هي 1000. وهذا يثبت أن المتغير المحلي N في الوظيفة F1 قد تم الاحتفاظ به في الذاكرة ولم يتم مسحه تلقائيًا بعد استدعاء F1.
لماذا هذا يحدث؟ والسبب هو أن F1 هو الدالة الأصل لـ F2 ، ويتم تعيين F2 لمتغير عالمي ، والذي يتسبب في أن يكون F2 دائمًا في الذاكرة ، ويعتمد وجود F2 على F1. لذلك ، يكون F1 دائمًا في الذاكرة ولن يتم إعادة تدويره بواسطة آلية جمع القمامة بعد الانتهاء من المكالمة.
هناك نقطة أخرى جديرة بالملاحظة في هذا الرمز وهي أن السطر "nadd = function () {n+= 1}" يستخدم لأول مرة قبل NADD ، لذلك NADD هو متغير عالمي ، وليس متغيرًا محليًا. ثانياً ، قيمة NADD هي وظيفة مجهولة ، وهذه الوظيفة المجهولة نفسها هي أيضًا إغلاق ، لذلك فإن NADD تعادل مراسلة ، والتي يمكن أن تعمل على المتغيرات المحلية داخل الوظيفة خارج الوظيفة.
5. الإغلاق وهذا الكائن
يمكن أن يسبب استخدام هذا الكائن في عمليات الإغلاق بعض المشكلات. لأن تنفيذ وظائف مجهولة هو عالمي ، فإن هذا الكائن عادة ما يشير إلى النافذة. الرمز كما يلي:
var name = "The Window" ؛ var object = {name: "كائن بلدي" ، getNameFun: function () {return function () {return this.name ؛} ؛}} ؛ ALERT (Object.getNameFun () {}) ؛ // "النافذة" (في الوضع غير المتخلف)احفظ هذا الكائن في النطاق الخارجي في متغير يمكن الوصول إليه عن طريق الإغلاق ، ويمكن للإغلاق الوصول إلى الكائن. الرمز كما يلي:
var name = "The Window" ؛ var object = {name: "كائن بلدي" ، getNameFun: function () {var that = this ؛ return function () {return that.name ؛} ؛}} ؛ ALERT (Object.getNameFun () {}) ؛ // "كائني"6. الإغلاق وتسرب الذاكرة
على وجه التحديد ، إذا تم تخزين عنصر HTML في نطاق الإغلاق ، فهذا يعني أنه لا يمكن تدمير العنصر. على النحو التالي:
الدالة issidhandler () {var element = document.getElementById ("somelement") ؛ element.onclick = function () {alert (element.id) ؛}}ينشئ الرمز أعلاه إغلاقًا كمعالج لحدث العناصر ، وهذا الإغلاق يخلق مرجعًا دائريًا. نظرًا لأن الوظائف المجهولة تحفظ مرجعًا إلى الكائن النشط لـ ExmentHandler () ، فلن يكون من الممكن تقليل عدد المراجع إلى العنصر. طالما وجود وظيفة مجهولة ، فإن عدد الإشارات إلى العنصر هو على الأقل 1 ، وبالتالي لن يتم إعادة تدوير الذاكرة التي يشغلها.
حل مشاكل إعادة التدوير الداخلية عن طريق إعادة كتابة الرمز:
الوظيفة issignHandler () {var element = document.getElementById ("somelement") ؛ var id = element.id ؛ element.onclick = function () {alert (id) ؛} element = null ؛}في الكود أعلاه ، لا يشير إغلاق التنفيذ مباشرة إلى العنصر ، وسيظل هناك مرجع في الكائن النشط الذي يحتوي على الوظيفة. لذلك ، من الضروري تعيين متغير العنصر على Null ، بحيث يمكن إعادة تدوير الذاكرة التي تحتلها بشكل طبيعي.
7. ملاحظات حول استخدام الإغلاق
1) نظرًا لأن عمليات الإغلاق سوف تتسبب في تخزين جميع المتغيرات في الوظيفة في الذاكرة ، ولا يمكن إساءة استخدام استهلاك الذاكرة ، ولا يمكن إساءة استخدامها ، وإلا فإنه سيؤدي إلى مشاكل في أداء صفحة الويب وقد يؤدي إلى تسرب الذاكرة في IE. الحل هو حذف جميع المتغيرات المحلية التي لا تستخدم قبل الخروج من الوظيفة.
2) سيغير الإغلاق قيمة المتغير داخل وظيفة الأصل خارج وظيفة الأصل. لذلك ، إذا كنت تستخدم وظيفة الأصل ككائن ، فاستخدم الإغلاق كطريقة عامة له ، واستخدم المتغير الداخلي كخاصية خاصة به ، فاحرص على عدم تغيير قيمة المتغير الداخلي لوظيفة الأصل في الإرادة.
ما سبق هو شرح مفصل لكتابة ووظيفة الإغلاق في جافا سكريبت المقدمة لك من قبل المحرر. آمل أن يكون ذلك مفيدًا لك. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر إليك في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!