وظيفة
تنسيق الوظيفة
دالة getProtyNames (o ،/*اختياري*/ a) {a = a || [] ؛ for (var p in o) {a.push (p) ؛} return a ؛}المتصل
FunC.Caller يعيد المتصل الوظيفة
وظيفة callfunc () {if (callfuncaller) {Alert (callfuncler.toString ()) ؛} آخر {Alert ("no function call") ؛}} function handlecaller ()كالي
طريقة مجهولة الهوية مكالمة عودية
ALERT ((function (x) {if (x <=) return ؛ return x * ediuments.callee (x -) ؛} ())) ؛ //نِطَاق
الجميع على دراية بالنطاق. سأتحدث اليوم عن مشكلة الإغلاق وفهم مشكلة الإغلاق بدقة.
<script> var global = "Global Scope" ؛ // هذا هو نطاق وظيفة النطاق العالمي () {var scope = "النطاق المحلي" ؛ // هذا هو نطاق إرجاع النطاق المحلي ؛ // النطاق الذي تم إرجاعه هو متغير محلي} </script>1: يمكن أيضًا الوصول إلى المتغيرات العالمية المحددة داخل الوظيفة . عندما يكون المتغير المحلي المحدد والاسم المتغير العالمي متماثلين ، فإن المتغير المحلي سيخفي المتغير العالمي ولن يدمر قيمة المتغير العالمي.
var scope = "Global Scope" ؛ function f () {var scope = "النطاق المحلي" ؛ نطاق الإرجاع ؛} التنبيه (f ()) ؛ // scopealert المحلي (النطاق) ؛ // النطاق العالمي ؛ما سبق سهل الفهم ، أليس كذلك؟
2. يمكن إعلان المتغيرات العالمية بدون VAR ، ولكن يجب الإعلان عن المتغيرات المحلية مع VAR. إذا لم تستخدم المتغيرات المحلية إعلان VAR ، فسيقوم برنامج التحويل البرمجي بالتخلي عن هذا كمتغير عالمي.
<span style = "line-height:.
ومع ذلك ، لا تستخدم المتغيرات العالمية إعلانات VAR ، وهي متاحة فقط لوضع غير متخلف. إذا تم استخدام الوضع الصارم ، فسيتم الإبلاغ عن خطأ.
<script> "استخدام صارم" ؛ Scope = "Global Scope" ؛ Function F () {Scope = "Scope Local" ؛ Return Scope ؛} ALERT (F ()) ؛ // SCOPEALERT LOCAL (SCOPE) ؛ // SCOPE </script>لذلك ، يوصى بعدم حذف VAR عند إعلان المتغيرات ، لأنه يمكن أن يتجنب المتاعب غير الضرورية.
3. لا بأس في الإعلان مقدمًا . ما هو قبل الموعد المحدد.
<script> "استخدام صارم" ؛ Scope ؛ console.log (Scope) ؛ var scope = "Global Scope" ؛ Console.log (Scope) ؛ </script>
قد يُنظر إلى هذا على أنه أول من يطبع غير محدد. نعم ، لم يتم تعيين قيمة بعد. يمكن أن تحدد المهمة التالية النطاق العالمي.
هذا ليس خطأ ، ولكن لماذا يحدث هذا؟ ألا ينبغي تحديد متغير قبل استخدامه؟
هنا سأخبرك عن سلسلة النطاق. JavaScript هي لغة النطاق المعجمية.
1. سلسلة النطاق هي كائن أو قائمة مرتبطة. تحدد مجموعة الكود هذه المتغيرات "في نطاق" هذا الرمز. عندما يحتاج JavaScript إلى العثور على نطاق المتغير ، فإنه سيتطور والبحث من الكائن الأول في السلسلة. إذا كان الكائن الأول هو النطاق ، فسيتم إرجاع قيمة هذا الكائن مباشرة. إذا لم يكن موجودًا ، فسيستمر في البحث في الكائن الثاني حتى يتم العثور عليه. إذا لم يتم العثور على المتغير في سلسلة النطاق ، فسيتم طرح خطأ.
يمكننا التعبير عن سلسلة الوظائف هذه على النحو التالي: Find Scope-> Window (الكائن العالمي) ثم يتم تعريف النطاق. ومع ذلك ، لم يتم تنفيذ عملية المهمة ، وتم تنفيذ عملية المهمة لاحقًا ، وبالتالي فإن القيمة غير محددة في هذا الوقت.
4. هذا أكثر إرباكًا. ما هي القيمة المطبوعة؟
<script> "استخدام صارم" ؛ var scope = "Global Scope" ؛ function f () {console.log (scope) ؛ var scope = "local scope" ؛ console.log (scope) ؛} f () ؛ </script>انظر هذا الرمز: إذا كنت مهملًا ، فيمكنك كتابة الإجابة الخاطئة:
1. النطاق gbal
2. النطاق المحلي
التحليل: إعلان المتغيرات العالمية. عندما يكون في هيئة الوظيفة ، يمثل أوله متغيرًا عالميًا ، بحيث يتم طباعة Global ، ويحدد المتغيرات المحلية الثانية ، التي تغطي النطاق العالمي ، لذلك تتم طباعة النطاق المحلي.
هذا التحليل صحيح تماما في ج# جافا. لكن التحليل هنا خاطئ بالفعل.
هذا يدل على أنه قبل هذه المشكلة ، دعونا نلقي نظرة على سؤال أولاً.
هذه الجملة مهمة للغاية: يتم تعريف المتغيرات العالمية دائمًا في البرنامج. يتم تعريف المتغيرات المحلية دائمًا داخل جسم الوظيفة التي تعلن عنها والوظائف التي تعششها.
إذا كنت تعمل بلغة رفيعة المستوى ، فأنت تتعرض لجافا سكريبت غير مناسب بعض الشيء لتعريف نطاقها. أنا نفس الشيء. لنلقي نظرة على مثال:
<script> var g = "Global Scope" ؛ function f () {for (var i = ؛ i <؛ i ++) {for (var j = ؛ j <؛ j ++) {؛} console.log (j) ؛} console.log (i) ؛ما هي نتيجة الطباعة؟
ترى أن {} يمثل كتلة بيان ، وأن كتلة العبارات في نطاق نفس الكتلة ، لذلك قد تخمن أن قيم J و I قد تم إصدارها في الذاكرة ، لذلك يجب أن تكون النتيجة غير محددة.
قد تخيبك النتيجة الحقيقية.
لماذا حدث هذا؟ بدأ تعبيري مثلك.
تحقق من الجملة التي طلبت منك أن تتذكر الآن. . . يتم تعريف المتغيرات العالمية دائمًا في البرنامج. يتم تعريف المتغيرات المحلية دائمًا داخل جسم الوظيفة التي تعلن عنها والوظائف التي تعششها.
لتصبح دقيقة ، تنتمي معلمات الوظيفة أيضًا إلى فئة المتغيرات المحلية. هذه الجملة مهمة جدا! ! !
هذه الجملة تعني تقريبًا أنه طالما أن المتغير المحدد داخل الوظيفة يكون صالحًا داخل الوظيفة بأكملها. لذلك ليس من الصعب فهم النتيجة. إذا نظرنا إلى الوراء في سؤالنا ، هل تفهم؟
تحتوي سلسلة العمل أيضًا على التعاريف التالية:
1. سلسلة العمل تتكون من كائن عالمي.
2. في جسم الوظيفة الذي لا يحتوي على تعشيش ، هناك كائنان في سلسلة العمل. يحدد الكائن الأول معلمات الوظيفة والمتغيرات المحلية ، والثاني هو الكائن العالمي.
3. في جسم الوظيفة المتداخلة ، هناك ثلاثة كائنات على الأقل في سلسلة العمل.
عندما يتم تعريف وظيفة ، سيتم حفظ سلسلة النطاق.
عندما يتم استدعاء هذه الوظيفة ، فإنها تنشئ كائنًا جديدًا لتخزين متغيراتها المحلية ويضيف هذا الكائن إلى سلسلة الإجراءات المحفوظة. في الوقت نفسه ، قم بإنشاء سلسلة جديدة من الوظائف التي تمثل مكالمات الوظائف.
بالنسبة للوظائف المتداخلة ، عندما يتم استدعاء الوظيفة الخارجية ، سيتم إعادة تعريف الوظيفة الداخلية مرة أخرى. لأنه في كل مرة تسمى وظيفة خارجية ، تختلف سلسلة العمل. الوظائف الداخلية لها اختلافات دقيقة في كل مرة يتم تعريفها. في كل مرة يتم استدعاء الوظيفة الخارجية ، يكون رمز الوظيفة الداخلية هو نفسه ، ونطاق الكود المرتبط مختلف أيضًا.
إنهاء
بعد القيام بذلك لفترة طويلة ، وتحدثت أخيرًا عن ذلك ، لكن دعنا نحلل النطاق من قبل.
<script> var nameg = "global" var g = function f () {console.log (name) ؛ function demo () {console.log ("demo =" + name) ؛} var name = "" nameg) ؛} demo () ؛ demo () ؛ demo () ؛} ؛ g () ؛ </script>نقوم بتحليل وفقًا لسلسلة العمل:
Call Demo0 ، Demo0 () -> Find Name ، غير موجود -> F () ، عودة
استدعاء Demo1 ، Demo1 ()-> البحث عن الاسم ، البحث ، العودة
Call Demo2 ، Demo2 () -> Find Nameg ، غير موجود -> f () للعثور على nameg ، غير موجود -> نافذة للعثور على nameg ، العودة.
انظر إلى هذا المثال:
<script> function f () {var count = ؛ return {counter: function () {return count ++ ؛} ، reft: function () {return count = ؛}}} var d = f () ؛ var c = f () ؛ console.log ("d first call:"+ d.counter () ؛ // console.log ( المكالمة الأولى: "+ c.counter ()) ؛ // </script>كما ترون في هذا المثال ، قمت بعملية العد والصراحة.
يتم إنشاء حالتين كائنات F ، لكل منهما سلسلة نطاقها الخاصة ، لذلك لا تؤثر قيمها على بعضها البعض. عندما يتم استدعاء C في المرة الثانية ، يتم حفظ قيمة العد لأن الكائن C لم يتم تدميره. فقط بعد فهم هذا المثال سيكون المثال التالي أسهل في الفهم.
يجب أن يكون الجميع واضحين جدًا بشأن هذه العملية. الآن دعونا نلقي نظرة على مشكلة الإغلاق. قمت بتعيين أربعة أزرار وانقر فوق كل زر لإرجاع اسم الاستجابة.
<Body> <script> function btninit () {for (var i = ؛ i <؛ i ++) {var btn = document.getElementById ("btn" + i) ؛ btn.addeventListener ("click" ، function () {Alert ("btn" + i) ؛}) ؛ id = "btn"> btn </utton> <button id = "btn"> btn </utton> <button id = "btn"> btn </ button> <button id = "btn"انقر للتشغيل ، ولكن النتيجة هي كل BTN5 ؛
جلسنا مع التحليل الآن. أولاً ، نحتاج إلى استدعاء الوظيفة المجهولة -> Find I ، ولم يتم العثور عليها -> btninit () ، ووجدت أنني في الحلقة. دُر. نحن نعلم أنه يتم إصدار مكالمة الوظيفة فقط ، وأن I In For مرئية دائمًا ، لذلك يتم الاحتفاظ آخر قيمة I. إذن كيف تحلها.
لحل المشكلة التي لا تكون قيمة I غير مرئية دائمًا في الوظيفة ، نحتاج إلى استخدام تعشيش الوظيفة ونمر القيمة I فيها.
الدالة btninit () {for (var i = ؛ i <؛ i ++) {(function (data_i) {var btn = document.getElementById ("btn" + data_i) ؛ btn.addeventListener ("انقر" ، الدالة () {ALERT ("btn" + data_i) ؛}) ؛}) ؛})بالنظر إلى الكود المعدل ، قم أولاً بتنفيذ الأول وإنشاء كائن. نقوم أولاً بتنفيذ الوظيفة المجهولة -> data_i ، ولكن لم يتم العثور عليها -> الوظيفة (data_i) ، ثم تنفيذها مرة أخرى لإنشاء كائن. تقول قواعد الإغلاق أنها لا تؤثر على بعضها البعض. لذلك يمكن الحصول على النتيجة الصحيحة.
ما سبق هو وظيفة JavaScript التي يجب أن تعرف (9) التي يقدمها لك المحرر. عند الحديث عن المعرفة ذات الصلة حول قضايا الإغلاق ، آمل أن يكون ذلك مفيدًا لك. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر إليك في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!