نادراً ما يتم استخدام وظائف الاتصال والتطبيق في بعض عمليات JavaScript البسيطة. في العمليات الكبيرة الأخرى ، مثل تطوير تطبيقات الويب ، يمكن مواجهة هاتين وظيفتين بشكل متكرر في تطوير إطار عمل JS. هناك أيضًا الكثير من المعلومات حول تفسيرات هاتين وظيفتين ، لكنني أعتقد أن الكثير من المعلومات إما مكتوبة أو متشابهة إلى حد كبير ، وتفتقر إلى التفسيرات المتصلة. بعد ذلك ، أحاول تحليل وشرح هاتين وظيفتين بفكرة أوضح وأبسط.
نسخة الكود كما يلي:
يمكننا النظر في Call () وتطبيق () كطرق لكائن معين ، والاتصال بشكل غير مباشر عن طريق استدعاء تنفيذ الطريقة. الوسيطة الأولى للاتصال () والتطبيق () هي الكائن الأصل للاتصال بالوظيفة. إنه سياق الدعوة ، ويتم الحصول على إشارة إليه من خلال هذا في جسم الوظيفة. للاتصال بالدالة f () على طريقة الكائن o ، يمكنك استخدام Call () وتطبيق () مثل هذا: F.Call (O) f.apply (O). [1]
دعنا نحلل المكالمة أولاً. فيما يلي شرح وظيفة الاتصال بواسطة ECMASCRIPT 3RD EDITION [2]: عندما يتم استدعاء طريقة الاتصال بواسطة كائن دالة (func.call (0)) ، يجب تمرير المعلمة اللازمة والعديد من المعلمات غير الضرورية.
a ، إذا لم يتم تشغيل الكائن الذي يتصل بالمكالمة ، يتم إلقاء خطأ من النوع.
ب ، اضبط قائمة المعلمات لتفريغ
C ، إذا تم تمرير الطريقة المدعوين أكثر من معلمة واحدة ، ثم أدخل Arg1 ، Arg2 ... في قائمة المعلمات بدورها
D ، إرجاع نتيجة استدعاء المكالمة ، استبدل هذا في وظيفة الاتصال (FUNC) بالمعلمة التي تم تمريرها 1 ، وعلاج قائمة المعلمات التي تم تمريرها كمعلمة لهذه الوظيفة.
في الواقع ، فإن وظيفة المكالمة هي النموذج الأولي لكائن الوظيفة. وهذا يعني أن الوظيفة التي يجب أن تكون المكالمات وظيفة أيضًا. عند استدعاء هذه المكالمة ، ما عليك سوى استبدال هذا في الوظيفة التي تستدعي المكالمة بالكائن الذي تم تمريره. هنا مثال:
<script> function c1 () {this.name = 'Zhang San' ؛ this.age = '24 '؛ this.sayname = function () {console.log ("هنا فئة C1 ، اسمي هو:"+this.name+"عمري"+this.age) ؛ }} الدالة c2 () {this.name = 'li si' ؛ this.age = '25 '؛ } var c1 = new C1 () ؛ var C2 = جديد C2 () ؛ c1.sayname () ؛ c1.sayname.call (c2) ؛ </script>نتائج التنفيذ:
فيما يلي فئة C1 ، اسمي: Zhang San يبلغ من العمر 24 عامًا
فيما يلي فئة C1 ، اسمي: Li Si عمري 25
في الكود أعلاه ، يتم الإعلان عن فئتين ، C1 و C2. يحتوي C1 على خصائصان ، طريقة واحدة ، و C2 لديها أيضًا خصائصان نفس C1. بعد الاستئصال ، يطبع c1.sayname () الخصائص الفعلية ، ولكن c1.sayname.call (c2) يطبع خصائص C2 ، لماذا هذا؟ نظرًا لأن SayName () هي وظيفة وهناك هذا في جسم الوظيفة ، عند تنفيذ المكالمة ، سيتم استبدال هذا بـ C2 ، وبالتالي سيتم طباعة سمة C2 في النهاية.
يكمن الفرق بين التطبيق والمكالمة في تمرير المعلمات الاختيارية. يتم تخزين جميع المعلمات الاختيارية للتطبيق في صفيف ، حيث يتم إدخال معلمة واحدة ، بينما يتم تمرير المكالمة إلى معلمات متعددة.
إذن ، ما هي تطبيقات التطبيق والاتصال؟ الأول هو العثور على أكبر عنصر في الصفيف الرقمي على الشبكة. يمكنك استخدام Math.max.apply (NULL ، ARRAY) مباشرة. والآخر هو استخدام التطبيق والاتصال بالوراثة ، على النحو التالي:
<script> وظيفة الإنسان (الاسم ، الجنس) {this.name = name ؛ this.Sex = الجنس ؛ this.walk = function () {console.log ('أنا أسير') ؛ }} وظيفة child () {human.call (هذا ، "Xiao Ming" ، "male") this.paly = function () {console.log ('أحب اللعب كثيرًا') ؛ } this.intruduce = function () {console.log ('hello every every ، i'+this.name) ؛ }} var jinp = new Human ('Jack' ، 'Male') ؛ var xiaoping = New Child () ؛ xiaoping.walk () ؛ xiaoping.paly () ؛ xiaoping.intruduce () ؛ </script>نتائج التنفيذ:
أنا أمشي
أحب اللعب كثيرا
مرحبا بالجميع ، أنا شياو مينغ
الوظيفة المماثلة لـ CALL () وتطبيقها () هي BIND () ، وهي طريقة جديدة تم إضافتها في ECMASCRIPT 5 ، ولكن يمكن محاكاةها بسهولة في ECMASCRIPT 3. وظيفة الربط هي أيضًا طريقة النمط النمط في JavaScript. المحتوى الرئيسي لهذه الطريقة هو ربط الوظيفة بكائن. عندما تكون طريقة BIND () مرتبطة بالوظيفة F () ويتم تمرير كائن O كمعلمة ، ستعود هذه الطريقة إلى وظيفة جديدة وسيتم تسميتها كوسيلة لـ O. سيتم نقل أي وسيطات تم تمريرها إلى الوظيفة الجديدة إلى الوظيفة الأصلية. على النحو التالي:
<script> Function Introduction (Country ، Hobby) {return "Hello everyion ، اسمي"+this.name+"، هذا العام"+this.age+"year ، from"+country+"، مثل"+hobby ؛ } var xiaoming = {name: "Xiao Ming" ، العمر: 20} var jieshao = induce.bind (xiaoming) ؛ console.log (jieshao ("China" ، "Play Ball") ؛ </script>نتائج التنفيذ:
مرحبًا بالجميع ، اسمي شياو مينغ ، عمري 20 عامًا ، من الصين ، أحب أن ألعب كرة السلة
المثال أعلاه يعادل:
<script> Function Introduction (Country ، Hobby) {return "Hello everyion ، اسمي"+this.name+"، هذا العام"+this.age+"year ، from"+country+"، مثل"+hobby ؛ } var xiaoming = {name: "Xiaoming" ، العمر: 20} console.log (induste.apply (xiaoming ، ["China" ، "play"])) ؛ // أو console.log (induce.call (Xiaoming ، "China" ، "Play")) ؛ </script>تجدر الإشارة إلى أنه في النمط الصارم لـ ECMASCRIPT 5 ، ستصبح أول وسيطة حقيقية للاتصال () وتطبيق () هذه القيمة ، حتى لو كانت تم تمريرها في الوسيطة الحقيقية هي القيمة الأصلية أو حتى الفريدة أو غير المحددة. في ECMASCRIPT 3 والوضع غير الشجري ، سيتم استبدال الفارغ غير المحدد وغير المحدد بالمواجهة العالمية ، بينما سيتم استبدال القيم الأصلية الأخرى بكائن التفاف المقابل.
مراجع
[1] ، دليل جافا سكريبت موثوق ، الطبعة السادسة ، صفحة 189
[2] ، function.prototype.call (thisarg [، Arg1 [، Arg2 ، ...]))
[3] ، function.prototype.apply (thisarg ، Argarray)