ما هو الإغلاق؟
دعونا نلقي نظرة على قطعة من الكود أولاً:
الدالة A () {var n = 0 ؛ دالة inc () {n ++ ؛ console.log (n) ؛ } شركة()؛ شركة()؛ } a () ؛ // مخرجات وحدة التحكم 1 ، ثم يخرج 2الأمر بسيط. دعونا نلقي نظرة على قطعة أخرى من الكود:
الدالة A () {var n = 0 ؛ this.inc = function () {n ++ ؛ console.log (n) ؛ } ؛} var c = new a () ؛ c.inc () ؛ // Console Output 1C.inc () ؛ // إخراج وحدة التحكم 2الأمر بسيط.
ما هو الإغلاق؟ هذا هو الإغلاق!
الوظائف التي لديها إمكانية الوصول إلى المتغيرات ضمن نطاق وظيفة أخرى هي الإغلاق. هنا تصل وظيفة INC إلى المتغير N في المُنشئ A ، بحيث يتم تشكيل الإغلاق.
دعونا نلقي نظرة على قطعة أخرى من الكود:
الدالة A () {var n = 0 ؛ دالة inc () {n ++ ؛ console.log (n) ؛ } return inc ؛} var c = a () ؛ c () ؛ // Console Output 1C () ؛ // إخراج وحدة التحكم 2دعونا نرى كيف يتم تنفيذها:
var c = couter () ، هذه الجملة COOTER () تُرجع الدالة inc ، ثم هذه الجملة تعادل var c = inc ؛
C () ، هذه الجملة تعادل INC () ؛ لاحظ أن اسم الوظيفة هو مجرد معرف (مؤشر إلى وظيفة) ، و () هو وظيفة التنفيذ.
الجمل الثلاث التالية المترجمة إلى: var c = inc ؛ شركة()؛ INC () ؛ ، هل هناك أي فرق بينه وبين الجزء الأول من الكود؟ لا.
ما هو الإغلاق؟ هذا هو الإغلاق!
تشبه جميع البرامج التعليمية للكتب المدرسية استخدام الفقرة الأخيرة لتوضيح عمليات الإغلاق ، لكنني أعتقد أن هذا يعقد المشكلة. ما يتم إرجاعه هنا هو اسم الوظيفة. قد لا يعكس الطلاب الذين لم يروا برمجة C/C ++ من Tan Haoqiang على الفور الفرق بين إحضار () أو لا ، مما يعني أن طريقة الكتابة هذه تأتي مع فخ. على الرغم من أن طريقة الكتابة هذه أكثر بروزًا ، إلا أنني ما زلت أرغب في تمييز المشكلة والنظر في الرمز 1 والرمز 2. ستظل في حيرة من أمرك بشأن دعوة الوظيفة ، هل ستشعر بالارتباك بشأن قيمة n؟
لماذا تحتاج إلى الكتابة مثل هذا؟
نحن نعلم أن كل وظيفة من JS هي غرفة سوداء صغيرة. يمكن أن تحصل على معلومات خارجية ، ولكن لا يمكن للعالم الخارجي رؤية المحتوى في الداخل مباشرة. وضع المتغير N في غرفة مظلمة صغيرة ، باستثناء وظيفة INC ، لا توجد طريقة أخرى للتواصل مع المتغير n. علاوة على ذلك ، فإن تحديد المتغير N بنفس الاسم خارج الوظيفة A لا يؤثر على بعضهما البعض. هذا هو ما يسمى تعزيز "التغليف".
السبب في أنك بحاجة إلى استخدام وظيفة الإرجاع إلى الإرجاع لتحديد INC هو أنه لا يمكن استدعاء وظيفة INC مباشرة خارج الوظيفة ، لذلك ترتبط Return Inc بالخارج. هذا في الكود 2 أيضا inciates Inc فقط مع الخارج.
مصائد شائعة
تحقق من هذا:
دالة createFunctions () {var result = new array () ؛ لـ (var i = 0 ؛ i <10 ؛ i ++) {result [i] = function () {return i ؛ } ؛ } نتيجة الإرجاع ؛} var funcs = createFunctions () ؛ لـ (var i = 0 ؛ i <funcs.length ؛ i ++) {console.log (funcs [i] ()) ؛}للوهلة الأولى ، اعتقدت أنه كان يخرج 0 ~ 9 ، لكنني لم أتوقع أن يخرج 10 10؟
الفخ هنا هو: الوظيفة مع () هي وظيفة التنفيذ! جملة بسيطة var f = function () {Alert ('hi') ؛ } ؛ لن يطفو على السطح ، والجملة التالية f () ؛ سيتم تنفيذ الكود داخل الوظيفة. تتم ترجمة الرمز أعلاه على النحو التالي:
var result = new array () ، i ؛ result [0] = function () {return i ؛ } ؛ // لم يتم تنفيذ الوظيفة ، تظل الوظيفة دون تغيير ، ولا يمكن استبدال I في الوظيفة! النتيجة [1] = function () {return i ؛ } ؛ // لم يتم تنفيذ الوظيفة ، تظل الوظيفة دون تغيير ، ولا يمكن استبدال I في الوظيفة! ... النتيجة [9] = function () {return i ؛ } ؛ // لم يتم تنفيذ الوظيفة ، تظل الوظيفة دون تغيير ، ولا يمكن استبدال I في الوظيفة! i = 10 ؛ funcs = result ؛ result = null ؛ console.log (i) ؛ // funcs [0] () هو تنفيذ بيان الإرجاع I ، وهو إرجاع 10console.log (i) ؛ // funcs [1] () هو تنفيذ بيان الإرجاع I ، وهو إرجاع 10 ... console.log (i) ؛ // funcs [9] () هو تنفيذ بيان الإرجاع I ، وهو إرجاع 10لماذا فقط نتائج جمع القمامة ولكن ليس أنا؟ لأنني ما زلت تتم الإشارة إليها من خلال الوظيفة. يشبه المطعم الذي تكون فيه اللوحات محدودة دائمًا ، لذلك سيذهب النادل إلى Patrol Taiwan لإعادة تدوير الألواح الفارغة ، ولكن كيف يجرؤ على جمع اللوحات التي لا تزال تحتوي على الخضروات؟ بالطبع ، إذا قمت بتسكع الأطباق يدويًا (= خالية) في اللوحة بنفسك ، فسيتم إبعاد اللوحة. هذه هي آلية إعادة تدوير الذاكرة المزعومة.
أما بالنسبة لكيفية عدم إمكانية الاحتفاظ بقيمة لي ، في الواقع ، فإن قراءتها على طول الطريق من بداية المقالة يجب ألا تكون أي شيء يدعو للقلق. أليس من الضروري تناول قطعة واحدة من الطبق على الطبق لتفقد قطعة واحدة؟
دعونا نلخص
الإغلاق هو متغير تشير الوظيفة إلى وظيفة أخرى. نظرًا لأنه يتم الرجوع إلى المتغير ، فلن يتم إعادة تدويره ، بحيث يمكن استخدامه لتغليف متغير خاص. هذه ميزة وعيب. الإغلاق غير الضروري سوف تزيد فقط من استهلاك الذاكرة! بالإضافة إلى ذلك ، عند استخدام الإغلاق ، يجب عليك أيضًا الانتباه إلى ما إذا كانت قيمة المتغير تلبي متطلباتك ، لأنها تشبه متغيرًا خاصًا ثابتًا. عادة ما يتم خلط عمليات الإغلاق مع العديد من الأشياء ، وفقط بعد الاتصال بهم بمزيد من الفهم ، يمكننا تعميق فهمنا. نحن هنا نتحدث فقط عن الأشياء الأساسية.
رابط لهذه المقالة: http://www.cnblogs.com/qieguo/p/5457040.html
ما سبق هو كل شيء عن هذا المقال ، آمل أن يكون مفيدًا لتعلم الجميع.