دعونا نعيد النظر في وظائف السهم.
وظائف السهم ليست مجرد "اختصار" لكتابة الأشياء الصغيرة. لديهم بعض الميزات المحددة والمفيدة للغاية.
جافا سكريبت مليئة بالمواقف التي نحتاج فيها إلى كتابة دالة صغيرة يتم تنفيذها في مكان آخر.
على سبيل المثال:
arr.forEach(func)
– يتم تنفيذ func
بواسطة forEach
لكل عنصر في المصفوفة.
setTimeout(func)
– يتم تنفيذ func
بواسطة برنامج الجدولة المدمج.
…هناك المزيد.
من روح JavaScript إنشاء وظيفة وتمريرها إلى مكان ما.
وفي مثل هذه الوظائف، لا نريد عادةً ترك السياق الحالي. هذا هو المكان الذي تكون فيه وظائف السهم مفيدة.
كما نتذكر من فصل أساليب الكائن، فإن وظائف السهم "هذا" لا تحتوي على this
. إذا تم الوصول إلى this
، فإنه يؤخذ من الخارج.
على سبيل المثال، يمكننا استخدامه للتكرار داخل تابع كائن:
دع المجموعة = { العنوان: "مجموعتنا"، الطلاب: ["جون"، "بيت"، "أليس"]، شوليست () { this.students.forEach( Student => تنبيه (this.title + ':' + Student) ); } }; group.showList();
هنا في forEach
، يتم استخدام وظيفة السهم، لذا فإن this.title
فيه هو نفسه تمامًا كما في الطريقة الخارجية showList
. وهذا هو: group.title
.
إذا استخدمنا دالة "عادية"، فسيكون هناك خطأ:
دع المجموعة = { العنوان: "مجموعتنا"، الطلاب: ["جون"، "بيت"، "أليس"]، شوليست () { this.students.forEach(وظيفة(طالب) { // خطأ: لا يمكن قراءة الخاصية "عنوان" غير محددة تنبيه(this.title + ':' + Student); }); } }; group.showList();
يحدث الخطأ لأن forEach
يقوم بتشغيل وظائف مع this=undefined
بشكل افتراضي، لذلك تتم محاولة الوصول إلى undefined.title
.
هذا لا يؤثر على وظائف الأسهم، لأنها لا تحتوي على this
.
لا يمكن تشغيل وظائف السهم باستخدام new
عدم وجود this
يعني بطبيعة الحال وجود قيد آخر: لا يمكن استخدام وظائف السهم كمنشئات. لا يمكن استدعاؤهم new
.
وظائف السهم مقابل الربط
هناك فرق دقيق بين دالة السهم =>
والدالة العادية التي يتم استدعاؤها باستخدام .bind(this)
:
يقوم .bind(this)
بإنشاء "نسخة مرتبطة" من الوظيفة.
السهم =>
لا ينشئ أي ربط. الوظيفة ببساطة لا تحتوي على this
. يتم البحث عن this
بنفس طريقة البحث عن المتغير العادي: في البيئة المعجمية الخارجية.
لا تحتوي وظائف السهم أيضًا على متغيرات arguments
.
يعد هذا أمرًا رائعًا لمصممي الديكور، عندما نحتاج إلى إعادة توجيه مكالمة باستخدام this
arguments
الحالية.
على سبيل المثال، يحصل defer(f, ms)
على دالة ويعيد غلافًا حولها يؤخر المكالمة بمقدار مللي ms
:
وظيفة التأجيل (و، مللي) { وظيفة العودة () { setTimeout(() => f.apply(this, الوسيطات), ms); }; } وظيفة قل مرحبا (من) { تنبيه ("مرحبا،" + من)؛ } Let sayHiDeferred = defer(sayHi, 2000); sayHiDeferred("جون"); // مرحبًا جون بعد ثانيتين
سيبدو الأمر نفسه بدون وظيفة السهم كما يلي:
وظيفة التأجيل (و، مللي) { وظيفة الإرجاع (...الوسائط) { دع ctx = هذا؛ setTimeout(وظيفة() { return f.apply(ctx, args); }، آنسة)؛ }; }
هنا كان علينا إنشاء متغيرات إضافية args
و ctx
حتى تتمكن الوظيفة الموجودة داخل setTimeout
من استيعابها.
وظائف السهم:
لا تملك this
ليس لديك arguments
لا يمكن استدعاؤه new
ليس لديهم أيضًا super
، لكننا لم ندرسه بعد. سنتحدث عن فصل الميراث الطبقي
وذلك لأنها مخصصة للأجزاء القصيرة من التعليمات البرمجية التي ليس لها "سياق" خاص بها، ولكنها تعمل في السياق الحالي. وهم يتألقون حقًا في حالة الاستخدام هذه.