إغلاق JS
ماذا تعرف قبل الإغلاق
1. نطاق الوظيفة
(1). الميزة الخاصة للغة JS هي أنه يمكن قراءة المتغيرات العالمية مباشرة داخل الوظائف
نسخة الكود كما يلي:
<script type = "text/javaScript">
var n = 100 ؛
وظيفة Parent () {
تنبيه (ن) ؛
}
Parent () ؛ // 100
</script>
إذا في PHP
نسخة الكود كما يلي:
<؟ PHP
$ n = 100 ؛
وظيفة Parent () {
صدى $ n ؛
}
Parent () ؛ // سيتم الإبلاغ عن الخطأ n لم يتم تعريف n
؟>
(2). لا يمكن قراءة المتغيرات المحلية داخل الوظيفة خارج الوظيفة
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة Parent () {
var m = 50 ؛
}
الوالدين () ؛
التنبيه (M) ؛ // لم يتم تعريف الخطأ M
</script>
لاحظ أنه عند إعلان المتغيرات داخليًا ، يجب عليك إضافة VAR ، وإلا سيتم الإعلان عن متغير عالمي.
نسخة الكود كما يلي:
وظيفة Parent () {
م = 50 ؛
}
الوالدين () ؛
تنبيه (M) ؛ // 50
// بالطبع هذا أكثر من ذلك في PHP.
نسخة الكود كما يلي:
<؟ PHP
وظيفة Parent () {
يجب فصل $ m ؛ // العالمية ، والتعريف والواجب
$ M = 50 ؛
}
الوالدين () ؛
صدى $ m ؛ // 50
؟>
// إذا لم يكن هناك عالمي ، فلن تكون هناك أخطاء في التعريف
في بعض الأحيان ، إذا كنت بحاجة إلى الحصول على متغيرات محلية داخل الوظيفة ، فأنت بحاجة إلى استخدام خصائص نطاق متغيرات JS. على سبيل المثال ، تحديد وظائف الطفل داخل الوظيفة ، بالنسبة لوظائف الطفل ، فإن وظيفة الوالدين هي عالمية ، ويمكن لوظيفة الطفل الوصول إلى المتغيرات في الدالة الأصل (لكود JS بأكمله ، وهو متغير محلي)
نسخة الكود كما يلي:
<script type = "text/javaScript">
وظيفة Parent () {
var m = 50 ؛
وظيفة الابن () {
تنبيه (م) ؛
}
عودة الابن
}
var s = parent () ؛ // حفظ النتيجة على مستوى العالم
S () ؛ // 50
</script>
جميع المتغيرات المحلية داخل الوالدين مرئية لوظائف أطفالهم ، ولكن المتغيرات المحلية داخل وظائف أطفالهم غير مرئية لوظائف الوالدين. هذا هو بنية نطاق السلسلة الفريدة ل JS. سيبحث الكائن الفرعي عن مستوى متغيرات جميع الكائنات الأصل حسب المستوى. جميع متغيرات الكائن الأصل مرئي للكائنات الفرعية ، وإلا فإنها لا تصدق! وظيفة الابن أعلاه هي إغلاق
قد يقوم بعض الطلاب بذلك
نسخة الكود كما يلي:
وظيفة Parent () {
var m = 50 ؛
وظيفة الابن () {
تنبيه (م) ؛
}
}
الوالدين () ؛
Son () // لم يتم تعريف الابن الوظيفي
لاحظ أنه في JavaScript ، تكون الوظائف المعلنة في الوظيفة محلية ، ويتم إصدارها بعد تشغيل الوظيفة.
انتبه إلى الفرق بين هذا و PHP
نسخة الكود كما يلي:
<؟ PHP
وظيفة Parent () {
وظيفة الابن () {
$ M = 50 ؛
صدى $ m ؛
}
}
الوالدين () ؛
الابن () ؛ // الإخراج 50 لن يبلغ عن خطأ
؟>
إنهاء
وظائف تحدد الوظائف داخليًا ، والجسور التي تربط الوظائف الداخلية والخارجية
هناك وظيفتان للإغلاق:
أولاً ، وظيفة القراءة داخل المتغيرات المذكورة أعلاه ،
والثاني هو حفظ قيم هذه المتغيرات في الذاكرة لتحقيق مشاركة البيانات
فيما يلي بعض الأمثلة على الإغلاق
نسخة الكود كما يلي:
<script type = "text/javaScript">
var cnt = (function () {
var i = 0 ؛
وظيفة الإرجاع () {
تنبيه (ط) ؛
i ++ ؛
}
}) () ؛
CNT () ؛ // 0
CNT () ؛ // 1
CNT () ؛ // 2
CNT () ؛ // 3
</script>
أقوم بحفظ نتيجة التنفيذ لوظيفة مجهولة (أي ، تعيين إعلان الوظيفي الفرعي إلى القطع المتغير العالمي) في الذاكرة
عند تنفيذ CUT () ، يتم استرداد القيمة مباشرة من الذاكرة. يمكن استدعاء وظيفة CNT () فقط ، وليس من الممكن التنبيه مباشرة (i)
يمكنك أيضًا نقل المعلمات إلى الإغلاق
نسخة الكود كما يلي:
var cnt = (function (num) {
وظيفة الإرجاع () {
تنبيه (num) ؛
num ++ ؛
}
}) (5) ؛
CNT () ؛ // 5
CNT () ؛ // 6
CNT () ؛ // 7
// بالطبع ، يمكنك أيضًا تمرير المعلمات عند الاتصال
var cnt = (function () {
var i = 0 ؛
وظيفة الإرجاع (num) {
num+= i ؛
تنبيه (num) ؛
i ++ ؛
}
}) () ؛
CNT (1) ؛ // 1
CNT (2) ؛ // 3
CNT (3) ؛ // 5
من أجل الحصول على فهم أفضل للإغلاق ، ننظر إلى الكود التالي
على سبيل المثال ، أريد إعادة صفيف مع 5 وظائف في المصفوفة ، وتظهر الوظيفة الأولى 0 ، والثانية تنبثق 1 ...
إذا تم كتابة الرمز مثل هذا
نسخة الكود كما يلي:
مربع الوظيفة () {
var arr = [] ؛
لـ (i = 0 ؛ i <5 ؛ i ++) {
arr = function () {return i ؛}
}
إرجاع arr ؛
}
var a = box () ؛
تنبيه (أ) ؛ // صفيف يحتوي على خمسة أجسام وظائف
تنبيه (A [0] ()) ؛
تنبيه (A [1] ()) ؛
جسم الوظيفة المنبثقة
function () {return i ؛}}
أخيرًا ، هذا هو 4 ، ثم يصبح ++ 5
للحلقة توقف
وقد وجد أن كل شيء برزت 5 ، والتي من الواضح أنها لم تلبي متطلباتنا
الحل 1
التنفيذ الذاتي للوظائف في الداخل
نسخة الكود كما يلي:
مربع الوظيفة () {
var arr = [] ؛
لـ (i = 0 ؛ i <5 ؛ i ++) {
arr = (function (num) {return i ؛}) (i) ؛
}
إرجاع arr ؛
}
var a = box () ؛
لـ (var i = 0 ؛ i <a.length ؛ i ++) {
تنبيه (أ) ؛
}
لكننا وجدنا أن العناصر الموجودة في الصفيف الذي تم إرجاعه هي نتيجة تنفيذ الوظيفة ، ولكن ما نريده هو أن الوظيفة تحتاج إلى ترقية.
الحل 2
تنفيذ الإغلاق
نسخة الكود كما يلي:
مربع الوظيفة () {
var arr = [] ؛
لـ (var i = 0 ؛ i <5 ؛ i ++) {
arr = (function (num) {
وظيفة الإرجاع () {return num ؛}
})(أنا)؛
}
إرجاع arr ؛
}
var arr = box () ؛
لـ (var i = 0 ؛ i <5 ؛ i ++) {
تنبيه (arr ()) ؛ // 0،1،2،3،4
}
رمز المفتاح
نسخة الكود كما يلي:
arr = (function (num) {
وظيفة الإرجاع () {return num ؛}
})(أنا)؛
عندما أنا = 0
arr [0] = (function (num) {return function () {return num ؛}}) (0) ؛
الساعة 1
arr [1] = (function (num) {return function () {return num ؛}}) (1) ؛
ما سبق هي فوائد الإغلاق! بسيطة جدا وعملية.