إذا لم تتعرض أبدًا للغات الديناميكية وفهمت JavaScript في عقلية اللغة المترجمة ، فستكون لديك شعور سحري وغريب ، لأن الأشياء التي غالباً ما تكون مستحيلة في الوعي ، وحتى تشعر بعدم المعقولة. إذا واجهت هذا الشعور في عملية تعلم JavaScript ، وهي لغة حرة لا نهاية لها ، ثم من النموذج الحالي ، فالرجاء التخلي عن "تحيزك" ، لأن هذا بالتأكيد عالم جديد بالنسبة لك ، دع JavaScript يذوب ببطء وعي البرمجة السابقة المتطورة وحقن حيوية جديدة!
حسنًا ، دعنا نعود إلى هذه النقطة ، أولاً نفهم خصائص سياق Javascrtipt التي تحولت ديناميكيًا. تنعكس هذه الخاصية بشكل أساسي في تطبيق طريقتين للتطبيق والاتصال.
للتمييز ، الطلب ، اتصل في جملة واحدة ،
foo.call (this ، arg1 ، arg2 ، arg3) == foo.apply (هذا ، الحجج) == this.foo (arg1 ، arg2 ، arg3)
اتصل وتطبيق كلاهما ينتمي إلى طريقة الوظيفة. النموذج. يتم تنفيذه بشكل جوهري بواسطة محرك JavaScript. نظرًا لأنه ينتمي إلى function.prototype ، كل مثيل كائن دالة ، أي أن كل طريقة لها سمة مكالمة وتطبيق. نظرًا لأنها خاصية للطريقة ، فإن استخدامها يهدف بالطبع إلى هذه الطريقة. من السهل الخلط بين هاتين الطريقتين لأنهما لهما نفس الوظيفة ، ولكن يتم استخدامهما بشكل مختلف.
أوجه التشابه: آثار الطريقتين هي نفسها بالضبط
الاختلافات: المعلمات التي تم تمريرها بواسطة الطريقة مختلفة
إذن ما هو تأثير الطريقة وما هي المعلمات التي تم تمريرها بالطريقة؟
دعونا نحلل foo.call أعلاه (هذا ، Arg1 ، Arg2 ، Arg3).
FOO هي طريقة ، هذا كائن مرتبط بالسياق عند تنفيذ الطريقة ، Arg1 و Arg2 و Arg3 هي معلمات تم تمريرها إلى طريقة FOO. الكائن المتعلق بالسياق المزعوم عند تنفيذ الطريقة ، إذا كان هناك أساس برمجة موجه للكائنات ، فمن السهل فهمه ، هذا في الكائن بعد إنشاء فئة.
في JavaScript ، يحتوي الكود دائمًا على كائن سياق ، ويقوم الرمز بمعالجةه. يتم تجسيد كائن السياق بواسطة هذا المتغير ، والذي يشير دائمًا إلى الكائن الذي يوجد فيه الكود الحالي.
من أجل فهم ما هو أفضل ، أعط مثالاً.
/إنشاء دالة الفئة A A () {// سيتم تشغيل الكود التالي عند إنشاء فئة // كائن سياق التنفيذ في هذا الوقت هو هذا ، وهو كائن المثيل الحالي this.message = "رسالة A" ؛ this.getMessage = function () {<span style = "white-space: pre"> </span> إرجاع this.message ؛ <span style = "white-space: pre"> </span>}} // إنشاء فئة A Object Object var a = new a () ؛ Class B Function B () {this.message = "Message of B" ؛ this.setMessage = function (msg) {<span style = "White-Space: pre"> </span> this.message = msg ؛ <span style = "White-Space: pre"> </span>}} // إنشاء كائن مثيل للفئة B var a = new b () ؛يمكن ملاحظة أن الفئتين A و B لها سمة رسالة (نحو الأعضاء المذكورة في الكائن). A لديه طريقة getMessage للحصول على الرسائل ، و B لديها طريقة setMessage لتعيين الرسائل. فيما يلي إظهار قوة المكالمة.
// Dynamic تعيين طريقة setMessage من B إلى الكائن أ. لاحظ أن نفسه ليس لديه هذه الطريقة! B.SetMessage.Call (A ، "رسالة A") ؛ // جميع عرض "رسالة" A "ALERT (A.GETMESSAGE ()) ؛ // Dynamic Envision the GetMessage method of a to object b. لاحظ أن B نفسه ليس لديه هذه الطريقة!
هذه هي قوة مكالمة JavaScript للغة الديناميكية!
إنه ببساطة "إنشاء شيء من لا شيء". يمكن تعيين طرق الكائن بشكل تعسفي ، لكن الكائن نفسه لم يكن لديه هذه الطريقة أبدًا. لاحظ أنه مهمة. من حيث Layman ، فإن الطريقة هي إقراض كائن آخر لإكمال المهمة. من حيث المبدأ ، يتغير كائن السياق عند تنفيذ الطريقة.
لذلك ، B.SetMessage.call (A ، "رسالة A") ؛ يعادل استخدام كائن سياق للاستدعاء طريقة setMessage لكائن B عند التنفيذ ، وهذه العملية ليس لها علاقة بـ B ، وتأثيرها يعادل A.SetMessage ("رسالة A") ؛
لأن تأثير التطبيق والمكالمة هو نفسه ، يمكن القول ذلك
اتصل ، تطبيق الوظيفة هي استعارة أساليب الآخرين للاتصال ، تمامًا مثل استدعاء المرء.
حسنًا ، بعد فهم أوجه التشابه بين المكالمة والتطبيق - بعد فهمها ، دعونا نلقي نظرة على خلافاتهم. بعد النظر إلى الأمثلة المذكورة أعلاه ، أعتقد أنك تعرف ذلك.
من B.SetMessage.Call (A ، "رسالة A") تعادل A.SetMessage ("رسالة A") يمكن رؤية أن "رسالة A" يتم تمريرها كمعلمة في المكالمة ،
فكيف يعني ذلك في التطبيق؟ من الصعب شرح ذلك بوضوح. يجب دمج التطبيق مع سيناريوهات التطبيق لتكون واضحة في لمحة. دعنا نتصميم سيناريو التطبيق:
وظيفة طباعة (A ، B ، C ، D) {ALERT (A + B + C + D) ؛} مثال على الوظيفة (A ، B ، C ، D) {// Borrow Print in the Call Method ، وتفرق بشكل صريح من المعلمات لتمرير Print.call (هذا ، A ، B ، C ، D) ؛ طريقة javaScript print. apply (هذا ، الوسيطات) ؛ // أو تغليفها في صفيف print.apply (هذا ، [a ، b ، c ، d]) ؛} // "النص الخلفي" ("Back" ، "Light" ، "Foot" ، "This") ؛) ؛في هذا السيناريو ، في طريقة المثال ، يتم استخدام A ، B ، C ، D كمعلمات تم تمريرها بواسطة الطريقة ، وتستخدم الأساليب تطبيق واتصل لاستعارة طريقة الطباعة للاتصال.
في الجملة الأخيرة ، نظرًا لأن طريقة المثال تسمى مباشرة ، فإن كائن السياق في هذه الطريقة هو كائن نافذة.
لذلك ، باستثناء المعلمة الأولى ، أي أن كائن السياق هو نفسه عند التنفيذ ، وسيتم تمرير المعلمات الأخرى لطريقة الاتصال إلى الطريقة المستعارة مثل المعلمات بدورها ، في حين أن التطبيق له معلمتان ، ويتم تمرير المعلمة الثانية في صفيف. لذلك يمكن القول ذلك
الفرق بين طرق الاتصال والتطبيق هو أنه بدءًا من المعلمة الثانية ، سيتم تمرير معلمات طريقة الاتصال إلى الطريقة المستعارة كمعلمات بدورها ، بينما يضع هذه المعلمات مباشرة في صفيف ثم يمررها. أخيرًا ، قائمة المعلمات بالطريقة المستعارة هي نفسها.
سيناريوهات التطبيق:
تتوفر المكالمة عندما تكون المعلمات واضحة ، ويمكن استخدام الوسائط عندما تكون المعلمات غير واضحة.
// مثال print.call (نافذة ، "الخلفية" ، "الضوء" ، "القدم" ، "هذا") ؛ // قد تكون معلمات FOO وظائف متعددة foo () {<span style = "White-Space: pre"> </span> print.apply (نافذة ، وسيطات) ؛}}تتفهم المقالة أعلاه بعمق الفرق بين أساليب التطبيق () و CALL () في JavaScript. إنه كل المحتوى الذي أشاركه معك. آمل أن تتمكن من إعطائك مرجعًا وآمل أن تتمكن من دعم wulin.com أكثر.