والمعلمات الفعلية ستظهر معلمات الوظيفة في مكانين، وهما مكان تعريف الوظيفة ومكان استدعاء الوظيفة، وتختلف المعلمات في هذين المكانين.
المعلمات الرسمية (المعلمات الرسمية)
يمكن اعتبار المعلمات التي تظهر في تعريف الوظيفة كعنصر نائب، ولا تحتوي على بيانات ويمكنها فقط الانتظار حتى يتم استدعاء الوظيفة لتلقي البيانات التي تم تمريرها، لذلك يطلق عليها معلمة رسمية، أو رسمية. المعلمة باختصار
المعلمات الفعلية (actual Parameters)
المعلمات المعطاة عند استدعاء الدالة تحتوي على بيانات حقيقية وسيتم استخدامها بواسطة الكود الموجود داخل الدالة، لذلك تسمى المعلمات الفعلية، أو المعلمات الفعلية للاختصار.
الفرق والاتصال بين المعلمات الرسمية والمعلمات الفعلية
1) ستخصص متغيرات المعلمات الرسمية الذاكرة فقط عند استدعاء الوظيفة، وبعد اكتمال الاستدعاء، سيتم تحرير الذاكرة على الفور، وبالتالي فإن متغيرات المعلمات الرسمية صالحة فقط داخل الوظيفة و لا يمكن استخدامها خارج الوظيفة.
2) يمكن أن تكون المعلمات الفعلية ثوابت، ومتغيرات، وتعبيرات، ووظائف، وما إلى ذلك. وبغض النظر عن نوع البيانات، فإن المعلمات الفعلية يجب أن يكون لها قيم معينة عند إجراء استدعاءات الوظائف من أجل نقل هذه القيم إلى المعلمات الرسمية لذا يجب عليك استخدام التعيين والإدخال وطرق أخرى مسبقًا للحصول على قيمة معينة للمعلمات الفعلية.
3) يجب أن تكون المعلمات الفعلية والمعلمات الرسمية متسقة تمامًا من حيث العدد والنوع والترتيب، وإلا سيحدث خطأ "عدم تطابق النوع". بالطبع، إذا كان التحويل التلقائي للنوع ممكنًا أو تم إجراء تحويل النوع القسري، فقد يختلف نوع المعلمة الفعلي أيضًا عن نوع المعلمة الرسمية.
4) يكون نقل البيانات الذي يحدث في استدعاء دالة في اتجاه واحد، ولا يمكن نقل قيمة المعلمة الفعلية إلا إلى المعلمة الرسمية، ولكن لا يمكن نقل قيمة المعلمة الرسمية إلى المعلمة الفعلية في الاتجاه العكسي وبعبارة أخرى، بمجرد اكتمال نقل البيانات، لم تعد المعلمات الفعلية والمعلمات الرسمية مرتبطة، لذلك أثناء استدعاء الوظيفة، لن تؤثر التغييرات في قيمة المعلمات الرسمية على المعلمات الفعلية.
5) على الرغم من أن المعلمات الرسمية والمعلمات الفعلية يمكن أن يكون لها نفس الاسم، إلا أنها مستقلة عن بعضها البعض ولا تؤثر على بعضها البعض، لأن المعلمات الفعلية صالحة خارج الوظيفة، بينما المعلمات الرسمية صالحة داخل الوظيفة.
تتمثل وظيفة المعلمات الرسمية والمعلمات الفعلية في تمرير البيانات. عند حدوث استدعاء دالة، سيتم تمرير قيمة المعلمة الفعلية إلى المعلمة الرسمية.
بتمرير البيانات، وتؤثر البيانات التي تم تمريرها على نتائج تنفيذ الوظيفة، مما يجعل الوظيفة أكثر مرونة وقابلة لإعادة الاستخدام.
وظيفة فو (أ، ب) { console.log([أ، ب])؛ } foo(1, 2); //
في هذا المثال للإخراج [1, 2]، يعد a
و b
متغيرين محليين في الوظيفة ولا يمكن الوصول إليهما إلا من خلال الوظيفة. عند استدعاء الوظيفة، ستتم مطابقة البيانات التي تم تمريرها وفقًا للموضع وتخصيصها إلى a
و b
على التوالي.
عند إنشاء دالة، تسمى المعلمات المحددة بين قوسين بعد function 函数名
معلمات رسمية ؛ عند استدعاء دالة، تسمى المعلمات التي تم تمريرها بين قوسين بعد اسم الوظيفة معلمات فعلية . في المثال أعلاه، a
و b
عبارة عن معلمات رسمية، والمعلمات التي تم تمريرها في 1
و 2
هي معلمات فعلية.
نظرًا لأن المعلمات الرسمية هي متغيرات مُعلنة، فلا يمكن الإعلان عنها بشكل متكرر باستخدام let
و const
.
وظيفة فو (أ، ب) { Let a = 1; // خطأ، تم الإعلان عن a const b = 1; // خطأ، تم الإعلان عن b}
يتم تمرير جميع عمليات نقل الوظائف في JavaScript حسب القيمة، وليس حسب المرجع. تشير القيمة المزعومة إلى القيمة المخزنة مباشرة على المتغير. إذا تم تمرير الكائن كمعلمة، فإن القيمة هي مرجع للكائن، وليس الكائن نفسه. هذه في الواقع عملية إسناد ضمنية، لذلك عند تمرير المعلمات إلى دالة، فإنها تعادل إسناد قيم من متغير إلى متغير آخر .
القيمة الأصلية:
الوظيفة add(num) { رقم الإرجاع + 1؛ } دعونا العد = 5؛ Let result = add(count); // يمكن اعتبار عملية تمرير المعلمة هنا num = count; console.log(count);// 5 console.log(result); // 6
القيمة المرجعية:
function setName(obj) { obj.name = "شياو مينغ"; } دع الشخص = {}؛ setName(person); // يمكن رؤية عملية تمرير المعلمة هنا على أنها obj = person; console.log(person); // {name: "Xiao Ming"}
لن تكتشف الوظائف في JavaScript نوع المعلمات ولا عدد المعلمات التي تم تمريرها. إن تعيين معلمتين رسميتين عند تعريف دالة لا يعني أنه يجب تمرير معلمتين عند الاتصال. عند الاتصال فعليًا، بغض النظر عما إذا تم تمرير معلمة واحدة أو ثلاث، فلن يتم الإبلاغ عن أي خطأ حتى إذا لم يتم تمرير أي معلمات.
يوجد كائن خاص يشبه المصفوفة يُسمى arguments
(وليس مثيلًا لـ Array
) في جميع الوظائف (غير الأسهم)، والذي يحتفظ بنسخة من جميع المعلمات الفعلية، ويمكننا استخدامه للحصول على قيم جميع المعلمات الفعلية وفقًا لذلك إلى طريقة الوصول إلى الفهرس لقيمة المصفوفة، يمكنك أيضًا الوصول إلى خاصية arguments.length
. الطول لتحديد عدد المعلمات التي تم تمريرها عند استدعاء الدالة فعليًا.
على سبيل المثال:
الدالة foo(a, b) { console.log(arguments[0]); console.log(arguments[1]); console.log(arguments.length); } foo(10, 20); // الإخراج 10، 20، 2 بالتسلسل
في المثال أعلاه، المعلمة الأولى لوظيفة foo() هي a، والمعلمة الثانية هي b، والتي يمكن الحصول عليها بشكل منفصل من خلال الوسائط[. س]. نفس القيمة. لذلك، يمكنك حتى الإعلان عن دالة دون تعيين معلمات رسمية.
وظيفة فو () { console.log(arguments[0]); console.log(arguments[1]); } foo(10, 20); // الإخراج 10 و 20 بالتسلسل
يمكن ملاحظة أن المعلمات الرسمية لوظيفة JavaScript مكتوبة فقط من أجل الراحة. لن يؤدي تمرير أي عدد تريده من المعلمات إلى حدوث خطأ.
شيء آخر يجب ملاحظته هو أنه يمكن استخدام arguments
مع المعلمات الرسمية، وستتم مزامنة القيم الموجودة في كائن arguments
مع المعلمات الرسمية المقابلة. على سبيل المثال:
الدالة foo(a) { الحجج[0]++; console.log(a); } فو (10)؛ // الإخراج 11 //---------------------------------------- وظيفة foo2(أ) { أ++; console.log(arguments[0]); } foo2(10); // الإخراج 11
عندما يتم تعديل قيمة الوسيطات [0] أو a، يتم تغيير القيمة الأخرى أيضًا. هذا لا يعني أنهم يصلون إلى نفس عنوان الذاكرة، ففي نهاية المطاف نقوم بتمرير قيمة بدائية. وهي لا تزال منفصلة في الذاكرة، لكن قيمها تظل متزامنة بسبب الآليات الداخلية.
بالإضافة إلى ذلك، إذا كانت المعلمة مفقودة، فلن تتم مزامنة قيمة هذه المعلمة الرسمية مع القيمة المقابلة في كائن arguments
. على سبيل المثال، في المثال التالي، يتم تمرير معلمة واحدة فقط، لذلك هناك قيمة معلمة فعلية واحدة فقط في arguments
. في هذا الوقت، إذا تم تعيين الوسيطات[1] على قيمة معينة في الوظيفة، فلن تتم مزامنة هذه القيمة إلى المعلمة الرسمية الثانية، على سبيل المثال:
function foo(a,b) { الحجج[1] = 2؛ console.log(b); } foo(1); // الإخراج غير محدد
في هذا المثال، لا تحتوي المعلمة الرسمية b على معلمة فعلية تم تمريرها، وستكون قيمتها الافتراضية undefined
. لكن إذا:
foo(1, uncategorized); //
عندما يتم تمرير الإخراج 2 يدويًا إلى undefined
، سيظهر عنصر ذو قيمة undefined
في مصفوفة arguments
، والتي لا يزال من الممكن مزامنتها مع قيمة b.
في الوضع الصارم ، لن تتم مزامنة القيم والمعلمات الرسمية في كائن arguments
. بالطبع، إذا تم تمرير القيم المرجعية، فستظل تؤثر على بعضها البعض، ولكن هذه مجرد خاصية للقيم المرجعية. لذلك، من الأفضل عدم الاعتماد على آلية المزامنة هذه أثناء التطوير، أي عدم استخدام المعلمات الرسمية والقيم المقابلة لها في كائن arguments
في نفس الوقت.
لا توجد وسائط في وظائف الأسهم
إذا تم تعريف الوظيفة باستخدام بناء جملة السهم، فلا توجد وسائط في الوظيفة ولا يمكن الوصول إليها إلا من خلال المعلمات الرسمية المحددة.
دع فو = () => { console.log(arguments[0]); }foo(); // خطأ، الوسائط غير محددة
في بعض الحالات، يمكن الوصول إلى arguments
:
function fn1(){. دع fn2 = () => { console.log(arguments[0]); } fn2(); }fn1(5);
لكن هذه arguments
ليست من وظيفة السهم، ولكنها تنتمي إلى الوظيفة العادية الخارجية. عند الوصول إلى arguments
في وظيفة السهم، يتم العثور arguments
الوظيفة الخارجية على طول سلسلة النطاق.
عندما تحتوي دالة على معلمات رسمية متعددة، يصبح استدعاء الوظيفة مشكلة، لأنه يتعين عليك دائمًا التأكد من وضع المعلمات التي تم تمريرها في الموضع الصحيح، هل هناك أي طريقة للحل؟ الحد من أمر تمرير المعلمة؟
وبما أن سمات الكائن غير مرتبة، يتم تحديد القيمة المقابلة حسب اسم السمة. لذلك، يمكنك تمرير الكائن واستخدام الخصائص الموجودة في الكائن كمعلمات حقيقية، لذلك لا يهم ترتيب المعلمات.
وظيفة فو (أوبج) { console.log(obj.name, obj.sex, obj.age); } foo({ sex: 'Male', age: 18, name: 'Xiao Ming' }); // Xiao Ming ذكر 18
إذا لم يتم توفير معلمات فعلية عند استدعاء دالة، فستكون القيمة الافتراضية من المعلمات الرسمية undefined
.
في بعض الأحيان نرغب في تعيين قيمة افتراضية محددة قبل ES6، عندما لم يكن تعيين القيمة الافتراضية بشكل صريح مدعومًا، كان بإمكاننا فقط استخدام الحل البديل:
function sayHi(name) { الاسم = الاسم ||. console.log( 'مرحبا' + اسم + '!'); } sayHi(); // إخراج "مرحبًا بالجميع!"
وتحديد ما إذا كان هناك أي تعيين عن طريق التحقق من قيمة المعلمة، على الرغم من أن الطريقة المذكورة أعلاه بسيطة، إلا أن العيب هو أنه إذا كانت المعلمة الفعلية الواردة تتوافق مع قيمة منطقية false
. المعلمة الفعلية لن تعمل إذا كنت بحاجة إلى مزيد من الدقة، يمكنك استخدام عبارة if
أو تعبير ثلاثي لتحديد ما إذا كانت المعلمة مساوية لـ undefined
، إذا كان الأمر كذلك، فهذا يعني أن المعلمة مفقودة:
// إذا حددت العبارة الوظيفة sayHi(name) {. إذا (الاسم === غير محدد) { الاسم = "الجميع"؛ } console.log( 'مرحبا' + اسم + '!'); } // وظيفة حكم التعبير الثلاثي sayHi(name) { الاسم = (الاسم!== غير محدد) الاسم: "الجميع"؛ console.log( 'مرحبا' + اسم + '!'); }
يعد ES6 أكثر ملاءمة لأنه يدعم الطريقة الصريحة لتعيين القيم الافتراضية، مثل هذا:
function sayHi(name = 'everyone') { // عند تعريف دالة، قم بتعيين قيم للمعلمات الرسمية مباشرة console.log( 'مرحبا' + اسم + '!'); } sayHi(); // الإخراج "مرحبًا بالجميع!" sayHi('توني'); // الإخراج "مرحبًا توني!" sayHi(undef); // الإخراج "مرحبًا بالجميع!"
توضح هذه النتائج أنها تحدد أيضًا ما إذا كانت المعلمة مفقودة من خلال ما إذا كانت المعلمة تساوي undefined
.
لا يمكن أن تكون القيمة الافتراضية قيمة فحسب، بل يمكن أيضًا أن تكون أي تعبير قانوني، حتى استدعاء دالة:
function sayHi(name = 'every'+'one') { console.log( 'مرحبا' + اسم + '!'); } sayHi(); // الإخراج "مرحبًا بالجميع!" //----------------------------------------- وظيفة فو () { console.log('استدعاء foo'); إرجاع "توني" ؛ } وظيفة sayHi(name = foo()) { console.log( 'مرحبا' + اسم + '!'); } sayHi(); // إخراج "استدعاء foo" // الإخراج "مرحبًا توني!" sayHi(undef); // إخراج "استدعاء foo" // الإخراج "مرحبًا توني!" sayHi('John'); // الإخراج 'Hello John!'
يمكنك أن ترى أن القيمة الافتراضية لمعلمة الدالة سيتم تقييمها فقط عندما يتم استدعاء الدالة وتكون قيمة المعلمة مفقودة أو undefined
، ولن يتم تقييمها يتم تقييمها عندما يتم تعريف الوظيفة.
عادةً ما نقوم بتعيين قيم افتراضية للمعلمات حتى نتمكن من حذف المعلمات بشكل مناسب عند استدعاء الوظيفة. ما يجب ملاحظته هنا هو أنه عندما تكون هناك معلمات متعددة، إذا لم يتم وضع المعلمة ذات القيمة الافتراضية في النهاية في الواقع من المستحيل حذفها.
وظيفة الجبهة الوطنية (س = 1، ص) { console.log([x, y]); } fn(); // الإخراج[1، غير محدد] الجبهة الوطنية (2)؛ // الإخراج [2، غير محدد] fn(, 2); // خطأ، خطأ في بناء الجملة (الفتحات الفارغة مثل المصفوفات غير مدعومة هنا) fn(undef, 2); // الإخراج [1, 2] (من الأفضل تمرير 1 للراحة!)
في المثال أعلاه، القيمة الافتراضية المحددة للمعلمة الرسمية x تبدو بلا معنى. لذلك، من الأفضل وضع المعلمات ذات القيم الافتراضية في النهاية:
دالة fn(x, y = 2) { console.log([x, y]); } fn(); // الإخراج[غير محدد، 2] الجبهة الوطنية (1)؛ // الإخراج [1، 2] الجبهة الوطنية (1، 1) // الإخراج [1، 1]مشكلة إغفال المعلمة
عندما يتم تعيين قيم افتراضية لمعلمات متعددة، تظهر المشكلة مرة أخرى، ولا يمكنك حذف المعلمات السابقة وتمرير المعلمات الفعلية فقط إلى المعلمة الأخيرة.
الدالة fn(x, y = 2, z = 3) { console.log([x, y, z]); } fn(1, , 10) // الإبلاغ عن خطأ
لقد علمنا سابقًا أنه يمكننا تجنب تقييد ترتيب المعلمات عن طريق تمرير الكائنات. كيفية تنفيذ القيم الافتراضية للمعلمات؟ استخدام ||
، if
العبارات أو التعبيرات الثلاثية للحكم هي أيضًا حل، لكن هذا يبدو متخلفًا بعض الشيء. التالي هو طريقتان جديدتان أخريان في ES6.
يتم استخدام القيم الافتراضية للمعلمات مع Object.assis()
وظيفة fn(obj = {}) { دع defaultObj = { س: غير محدد، ص: 2، ض: 3 } Let result = Object.assis(defaultObj, obj); console.log([result.x, result.y, result.z]); } fn(); // الإخراج [غير محدد، 2، 3] fn({ x: 1, z: 10 }); // الإخراج [1, 2, 10]
في المثال أعلاه، يتم تعريف كائن defaultObj
في الوظيفة، ويتم استخدام الخصائص الموجودة فيه كقيم افتراضية للمعلمات. ثم يتم استخدام Object.assagin() لدمج الكائن الوارد والكائن الافتراضي سيتم تجاوز الخصائص في defaultObj. سيتم تجاوز نفس سمات obj. إذا كانت هناك سمات أخرى في obj، فسيتم تعيينها إلى defaultObj. هنا يتم استخدام متغير لتلقي الكائن المدمج الذي تم إرجاعه.
في الوقت نفسه، يتم أيضًا تعيين القيمة الافتراضية للمعلمة الرسمية obj
على كائن فارغ لمنع عدم تمرير أي معلمات عند استدعاء الوظيفة، لأن هذا سيؤدي إلى undefined
المعلمة الثانية التي يتلقاها Object.assis() ، مما أدى إلى حدوث خطأ.
يتم استخدام القيم الافتراضية للمعلمات ومهام التدمير معًا
عندما يتم استدعاء دالة، فإن مطابقة المعلمات الفعلية والمعلمات الرسمية هي في الواقع عملية تعيين ضمنية، لذلك يمكن أيضًا تفكيك تمرير المعلمات وتعيينها:
الدالة fn({ x, y = 2, z = 3 }) { console.log([x, y, z]); } fn({}); // الإخراج [غير محدد، 2، 3] fn({ x: 1, z: 10 }); // الإخراج [1, 2, 10]
في هذا المثال، يتم استخدام القيمة الافتراضية لمهمة تدمير الكائن فقط، ولا يتم استخدام القيمة الافتراضية لمعلمة الوظيفة. إذا لم يتم تمرير أي معلمات عند استدعاء الوظيفة، فسيتم الإبلاغ عن خطأ أيضًا، لأن هذا سيؤدي إلى فشل مهمة التدمير أثناء تهيئة المعلمة، وهو ما يعادل تنفيذ تعليمات برمجية مثل {x, y = 2, z = 3} = undefined
.
وبالمثل، يمكنك استخدام بناء جملة القيم الافتراضية للمعلمات لتعيين كائن تدمير افتراضي لـ {x, y = 2, z = 3}
، بحيث يمكن تنفيذ الوظائف دون تمرير المعلمات بسلاسة:
الدالة fn({ x, y = 2, z = 3 } = {}) { console.log([x, y, z]); } fn(); // الإخراج [غير محدد، 2، 3]
توجد قيم افتراضية مزدوجة هنا، والتي قد تكون مربكة بعض الشيء، لذا استخدم جزءًا من التعليمات البرمجية الزائفة لشرح عملية تهيئة المعلمة أعلاه:
إذا (المعلمات الفعلية === {...}) {// عندما fn({...}); { س، ص = 2، ض = 3 } = {...}; } else if (المعلمة الفعلية === غير محددة ){ // عندما fn(); { س، ص = 2، ض = 3 } = {}; }
هناك تفصيل واحد يتطلب اهتمامًا خاصًا بالقيم الافتراضية المزدوجة، وهو الفرق بين القيمة الافتراضية لمهمة التدمير والقيمة الافتراضية لمعلمة الوظيفة. انظر المثال التالي:
الدالة fn ({ x = 1 } = {}, { y } = { y: 2 }){ console.log(x, y); } fn(); // الإخراج 1 2 fn({ x: 10 }, { y: 20 }); // الإخراج 10 20 fn({},{}); // 1 غير محدد
في هذه الوظيفة، هناك مجموعتان من المعلمات التي تستخدم مهمة التدمير. يبدو أن كلا من x و y لهما قيم افتراضية محددة. على الرغم من أنهما شكلان مختلفان، فمن الواضح أن النتائج ليست هي نفسها في كل حالة. عندما تكون المعلمة التي تم تمريرها هي {}
، لا تحصل y على القيمة الافتراضية 2. لماذا هذا؟ بالدمج مع مثال الكود الكاذب السابق:
fn({ x: 10 }, { y: 20 }); // أثناء التهيئة: { x = 1 } = { x: 10 }, { y } = { y: 20 } fn({},{}); // أثناء التهيئة: { x = 1 } = {}, { y } = {}
عندما تكون المعلمة التي تم تمريرها هي {}
، فإن معلمة الدالة ليست مفقودة أو undefined
، وبالتالي فإن القيمة الافتراضية لمعلمة الدالة ليس لها أي تأثير. في الوقت نفسه، لا توجد قيم مقابلة لـ x وy في {}
1 التي تم الحصول عليها بواسطة x هي القيمة الافتراضية لمهمة التدمير، ولا تحتوي y على قيمة افتراضية لمهمة التدمير، لذا فهي افتراضية undefined
. .
النطاق والمنطقة الميتة المؤقتة للقيم الافتراضية للمعلمات
هناك تفاصيل صغيرة أخرى بمجرد تعيين المعلمات على القيم الافتراضية، فإنها ستشكل نطاقًا خاصًا بها (مغلفًا في (...)
)، لذلك لا يمكن الرجوع إلى المتغيرات في نص الدالة:
وظيفة فو (أ = ب) { دع ب = 1؛ } foo(); // خطأ، b غير محدد
ولكن هذا النطاق مؤقت فقط بعد تهيئة المعلمات، لن يعد هذا النطاق موجودًا.
كما أنه يتبع قواعد النطاقات العادية:
دع ب = 2؛ وظيفة فو (أ = ب) { دع ب = 1؛ العودة أ؛ } فو(); // 2
في المثال أعلاه، يوجد متغير عام b، ثم ستحصل المعلمة الرسمية a على قيمة المتغير العام b.
بالطبع، إذا كانت هناك معلمة رسمية b في نطاق المعلمة الرسمية، فستحصل أولاً على النطاق الحالي:
دع ب = 2؛ وظيفة فو(ب = 3،أ = ب) { العودة أ؛ } فو(); // 3
قم بتعيين القيم الافتراضية لمعلمات متعددة، وسيتم تهيئتها بالترتيب، باتباع قواعد "المنطقة الميتة المؤقتة"، أي أن المعلمات السابقة لا يمكن أن تشير إلى المعلمات الأحدث:
وظيفة فو(أ = ب، ب = 2) { العودة أ + ب؛ } foo(); // خطأ، لا يمكن الوصول إلى b قبل التهيئة
المعلمات المتبقية
يوفر ES6 بناء جملة **المعلمات المتبقية (الراحة)** ( ...变量名
)، والتي يمكنها جمع المعلمات الفعلية الزائدة عن الحاجة للوظيفة (أي المعلمات الفعلية التي لا تتوافق مع المعلمات الرسمية)، بحيث لا يكون هناك بحاجة إلى استخدام كائن arguments
حصلت عليه. إذا تم استخدام المعلمة الرسمية مع عامل التشغيل ...
، فسوف تصبح مصفوفة، وسيتم وضع المعلمات الفعلية الزائدة في هذه المصفوفة.
الاستخدام الأساسي للمعلمات المتبقية:
مجموع الدالة (أ، ...القيم) { لـ (دع فال القيم) { أ += فال؛ } العودة أ؛ } مجموع(0, 1, 2, 3);
في المثال أعلاه، أثناء تهيئة المعلمة، يتم إجراء المطابقة أولاً بناءً على موضع المعلمة، ويتم تعيين 0 إلى a، ثم سيتم وضع المعلمات المتبقية 1 و2 و3 في قيم المصفوفة.
فيما يلي مثال مقارنة لاستخدام كائنات arguments
والمعلمات المتبقية للحصول على المعلمات:
// كيفية كتابة الوسائط functionsortNumbers() { return Array.prototype.slice.call(arguments).sort(); } // كيفية كتابة المعلمات المتبقية constsortNumbers = (...numbers) => { إرجاع الأرقام. }
يمكن ملاحظة أن المعلمات المتبقية مكتوبة بشكل أكثر إيجازًا. على الرغم من أن arguments
عبارة عن كائن يشبه المصفوفة وكائن قابل للتكرار، إلا أنها ليست مصفوفة على الإطلاق. لا يدعم أساليب المصفوفة. عندما نستخدم arguments
، إذا أردنا استدعاء طريقة مصفوفة، فيجب علينا استخدام Array.prototype.slice.call
لتحويلها إلى مصفوفة أولاً.
تختلف المعلمات المتبقية عن كائن arguments
، فهي مثيلات Array
حقيقية ويمكنها بسهولة استخدام طريقة المصفوفة. وتدعم وظائف الأسهم أيضًا المعلمات المتبقية.
بالإضافة إلى ذلك، فإن استخدام المعلمات المتبقية لا يؤثر على وظيفة كائن arguments
، بل لا يزال من الممكن أن يعكس المعلمات التي تم تمريرها عند استدعاء الوظيفة.
موقف المعلمات المتبقية
يجب أن تكون المعلمة المتبقية هي المعلمة الرسمية الأخيرة، وإلا سيتم الإبلاغ عن خطأ.
// وظيفة الإبلاغ عن الأخطاء fn1(a, ...rest, b) { console.log([أ، ب، راحة])؛ } // الطريقة الصحيحة لكتابة الدالة fn2(a, b, ...rest) { console.log([أ، ب، راحة])؛ } fn2(1, 2, 3, 4) // الإخراج [1, 2, [3, 4]]
قم بتوسيع بناء الجملة
كنا نعرف سابقًا كيفية جمع المعلمات الزائدة في مصفوفة، لكن في بعض الأحيان نحتاج إلى القيام بالعكس، مثل تمرير العناصر الموجودة في مصفوفة إلى دالة بشكل منفصل بدلاً من تمريرها في مصفوفة، كما يلي:
مجموع الدالة(...القيم) { دع المبلغ = 0؛ لـ (دع فال القيم) { مجموع += فال؛ } مبلغ الإرجاع؛ } دع arr = [1, 2, 3, 4]; مجموع (arr)؛ // "01،2،3،4"
الدالة في المثال أعلاه سوف تقوم بتجميع كل القيم التي تم تمريرها. إذا مررناها في مصفوفة مباشرة، فلن نحصل على النتيجة التي نريدها.
في المثال، إذا تم تمرير مصفوفة، ستصبح قيمة القيم [[1, 2, 3, 4]]
، وينتج عن ذلك عنصر واحد فقط في قيم المصفوفة، ونوع هذا العنصر هو مصفوفة . ثم تكون القيمة المرجعة للوظيفة هي نتيجة إضافة القيمة 0
والمصفوفة [1, 2, 3, 4]
ويتم تحويل هذين النوعين ضمنيًا إلى سلاسل، ثم يتم إضافتهما معًا.
لتفكيك المصفوفة وتمريرها إلى الوظيفة، من المستحيل أولاً تمرير المعلمات واحدة تلو الأخرى - sum(arr[0], arr[1], arr[2], arr[3]);
لأنه ليس من الممكن دائمًا أن تعرف عدد العناصر الموجودة في المصفوفة، وقد يكون هناك الكثير من العناصر في المصفوفة، ومن غير الحكمة تمريرها يدويًا.
من الأفضل استخدام طريقة application() :
sum.apply(null, arr);
ولكن هذا ليس الحل الأمثل بعد، وهنا تأتي النقطة الأساسية!
يمكن أن يساعدنا **بناء الجملة (الانتشار)** الجديد في ES6 في مواجهة هذا الموقف. ويستخدم أيضًا ...变量名
، على الرغم من أنه هو نفس بناء جملة المعلمة المتبقية، إلا أن غرضه معاكس تمامًا.
عند استدعاء الدالة يكون تطبيقها كما يلي:
مجموع (... آر)؛ // 10 // يعادل المجموع(1,2,3,4);
ويمكن أيضًا استخدامه مع القيم العادية حسب الرغبة، ولا توجد قيود على المواضع الأمامية والخلفية، ويمكن تمرير كائنات متعددة قابلة للتكرار في نفس الوقت:
مجموع(-1, ...arr); مجموع (... آر، 5)؛ مجموع(-1, ...arr, 5); sum(-1, ...arr, ...[5, 6, 7]); // 27
عامل التوسيع ...
يعادل إكمال عملية تمرير المعلمات يدويًا بشكل منفصل بالنسبة لنا. تعرف الوظيفة فقط أن المعلمات الفعلية المستلمة هي قيم فردية، ولن يكون لها تأثيرات أخرى بسبب وجود عامل التوسيع.
على الرغم من أن الأمثلة المذكورة أعلاه مخصصة للمصفوفات، إلا أن بناء الجملة الموسع يمكن أن يفعل أكثر من ذلك، ويمكن توسيع الكائنات القابلة للتكرار الأخرى مثل السلاسل والكائنات الحرفية لمزيد من المعلومات، يرجى الاطلاع على → بناء الجملة الموسع
المعلمات الرسمية هي متغيرات محلية تم الإعلان عنها في الوظيفة، وسيتم تعيين المعلمات الفعلية التي تم تمريرها إلى الوظيفة إلى المعلمات الرسمية.
قد لا يكون عدد المعلمات الرسمية والمعلمات الفعلية متساويًا:
● ستحصل المعلمات الرسمية التي لا تحتوي على معلمات فعلية على القيمة الافتراضية undefined
.
● يمكن الوصول إلى معلمات فعلية إضافية من خلال كائن arguments
، باستثناء وظائف الأسهم.
يمكنك تمرير الكائن بحيث لا يعد ترتيب تمرير المعلمات مهمًا، والسماح باستخدام الخصائص الموجودة في الكائن كمعلمات حقيقية.
القيمة الافتراضية لمعلمة ES6 - سيتم الحصول على القيمة الافتراضية فقط إذا كانت قيمة المعلمة مفقودة أو undefined
عند استدعاء الوظيفة.
● لا يمكن حذف المعلمات التي تحدد القيم الافتراضية إلا إذا تم وضعها في الموضع الأخير.
● لا يمكن أن تشير القيمة الافتراضية لإعداد المعلمة الرسمية إلى المتغيرات الموجودة في نص الوظيفة، ولكن يمكن أن تشير إلى المعلمات الرسمية السابقة والمتغيرات الخارجية.
● يمكن أن يؤدي تنفيذ القيم الافتراضية من خلال Object.assis() أو مهمة التدمير إلى جعل طريقة تمرير المعلمات أكثر مرونة.
الفرق الرئيسي بين المعلمات arguments
المتبقية:
● تحتوي المعلمات المتبقية فقط على المعلمات الفعلية التي لا تحتوي على معلمات رسمية مقابلة، بينما يحتوي كائن arguments
على كافة المعلمات الفعلية التي تم تمريرها إلى الوظيفة.
● المعلمات المتبقية هي مثيلات Array
حقيقية، بينما arguments
هي مجرد كائنات تشبه المصفوفة.
تستخدم كل من المعلمات المتبقية وبناء جملة التوسيع عامل التشغيل ...
، في السيناريوهات المتعلقة بالوظيفة:
● يظهر في نهاية قائمة معلمات الوظيفة وهو المعلمة المتبقية.
● يحدث في استدعاءات الوظائف، وهو عبارة عن بناء جملة موسع.
ما ورد أعلاه هو مقال يشرح تفاصيل المعلمات في وظائف JavaScript. لمزيد من المعلومات، يرجى الانتباه إلى المقالات الأخرى ذات الصلة على موقع php الصيني!