كيفية استخدام معاملات ومعلمات ES6

نشرت: 2022-03-10
ملخص سريع ↬ يستخدم المطورون ميزات ECMAScript 6 أكثر وأكثر ، وقريبًا ستكون هذه الميزات حتمية. في هذا البرنامج التعليمي ، ستتعرف على كيفية قيام ECMAScript 6 بترقية معالجة المعلمات في JavaScript والمزيد.

ECMAScript 6 (أو ECMAScript 2015) هو أحدث إصدار من معيار ECMAScript وقد تحسن بشكل ملحوظ من معالجة المعلمات في JavaScript. يمكننا الآن استخدام معلمات الراحة والقيم الافتراضية والتدمير ، من بين ميزات جديدة أخرى.

في هذا البرنامج التعليمي ، سوف نستكشف الحجج والمعلمات بالتفصيل ونرى كيف قام ECMAScript 6 بترقيتها.

الحجج مقابل المعلمات

غالبًا ما يُشار إلى الحجج والمعلمات بالتبادل. ومع ذلك ، لغرض هذا البرنامج التعليمي ، سنقوم بالتمييز. في معظم المعايير ، المعلمات (أو المعلمات الرسمية) هي ما يتم تقديمه في إعلان الوظيفة ، والوسيطات (أو المعلمات الفعلية) هي ما يتم تمريره إلى الوظيفة. ضع في اعتبارك هذه الوظيفة:

 function foo(param1, param2) { // do something } foo(10, 20);

في هذه الدالة ، تعد param1 و param2 معلمات دالة ، والقيم التي تم تمريرها إلى الدالة ( 10 و 20 ) هي وسيطات.

عامل الانتشار (...)

في ECMAScript 5 ، تعد طريقة apply() أداة ملائمة لتمرير مصفوفة كوسيطات إلى دالة. على سبيل المثال ، يتم استخدامه بشكل شائع مع طريقة Math.max() للعثور على أعلى قيمة في المصفوفة. ضع في اعتبارك جزء التعليمات البرمجية هذا:

 var myArray = [5, 10, 50]; Math.max(myArray); // Error: NaN Math.max.apply(Math, myArray); // 50

لا يدعم أسلوب Math.max() المصفوفات ؛ لا يقبل سوى الأرقام. عندما يتم تمرير مصفوفة إلى Math.max() ، فإنها تتسبب في خطأ. ولكن عند استخدام طريقة application ( apply() ، يتم إرسال المصفوفة كأرقام فردية ، بحيث يمكن Math.max() معالجتها.

المزيد بعد القفز! أكمل القراءة أدناه ↓

لحسن الحظ ، مع إدخال عامل الانتشار في ECMAScript 6 ، لم نعد بحاجة إلى استخدام طريقة apply() . باستخدام عامل الانتشار ، يمكننا بسهولة توسيع تعبير ما إلى عدة وسيطات:

 var myArray = [5, 10, 50]; Math.max(...myArray); // 50

هنا ، يقوم عامل التشغيل بتوسيع myArray لإنشاء قيم فردية للدالة. أثناء محاكاة عامل الانتشار باستخدام application apply() في ECMAScript 5 ، يكون بناء الجملة محيرًا ويفتقر إلى مرونة عامل الانتشار. عامل الانتشار ليس أسهل في الاستخدام فحسب ، بل يضم المزيد من الميزات. على سبيل المثال ، يمكن استخدامه عدة مرات ويمكن مزجه مع وسيطات أخرى في استدعاء function :

 function myFunction() { for(var i in arguments){ console.log(arguments[i]); } } var params = [10, 15]; myFunction(5, ...params, 20, ...[25]); // 5 10 15 20 25

ميزة أخرى لعامل الانتشار هي أنه يمكن استخدامه بسهولة مع المنشئين:

 new Date(...[2016, 5, 6]); // Mon Jun 06 2016 00:00:00 GMT-0700 (Pacific Daylight Time)

بالطبع ، يمكننا إعادة كتابة الكود السابق في ECMAScript 5 ، لكننا سنحتاج إلى استخدام نمط معقد لتجنب حدوث خطأ في النوع:

 new Date.apply(null, [2016, 4, 24]); // TypeError: Date.apply is not a constructor new (Function.prototype.bind.apply(Date, [null].concat([2016, 5, 6]))); // Mon Jun 06 2016 00:00:00 GMT-0700 (Pacific Daylight Time)

انتشار دعم متصفح عامل التشغيل في المكالمات الوظيفية

متصفحات سطح المكتب:

كروم ثعلب النار متصفح الانترنت مايكروسوفت إيدج أوبرا سفاري
46 27 - أيد - 7.1

متصفحات الجوال:

Chrome لنظام Android فايرفوكس موبايل سفاري موبايل أوبرا موبايل IE موبايل
46 27 8 - -

معلمات الراحة

المعلمة rest لها نفس صيغة عامل الانتشار ، ولكن بدلاً من توسيع المصفوفة إلى معلمات ، فإنها تجمع المعلمات وتحولها إلى مصفوفة.

 function myFunction(...options) { return options; } myFunction('a', 'b', 'c'); // ["a", "b", "c"]

إذا لم تكن هناك متغيرات ، فسيتم تعيين المعامل rest على مصفوفة فارغة:

 function myFunction(...options) { return options; } myFunction(); // []

تكون معلمة الراحة مفيدة بشكل خاص عند إنشاء دالة متغيرة (دالة تقبل عددًا متغيرًا من الوسائط). من خلال الاستفادة من كونها مصفوفات ، يمكن لمعلمات الباقي أن تحل محل الكائن arguments (الذي سنشرحه لاحقًا في هذا البرنامج التعليمي). ضع في اعتبارك هذه الوظيفة ، المكتوبة في ECMAScript 5:

 function checkSubstrings(string) { for (var i = 1; i < arguments.length; i++) { if (string.indexOf(arguments[i]) === -1) { return false; } } return true; } checkSubstrings('this is a string', 'is', 'this'); // true

تتحقق هذه الوظيفة مما إذا كانت السلسلة تحتوي على عدد من السلاسل الفرعية. المشكلة الأولى في هذه الوظيفة هي أننا يجب أن ننظر داخل جسم function لنرى أنه يتطلب عدة وسيطات. المشكلة الثانية هي أن التكرار يجب أن يبدأ من 1 بدلاً من 0 ، لأن arguments[0] تشير إلى الوسيطة الأولى. إذا قررنا لاحقًا إضافة معلمة أخرى قبل السلسلة النصية أو بعدها ، فقد ننسى تحديث الحلقة. مع باقي المعلمات ، يمكننا بسهولة تجنب هذه المشكلات:

 function checkSubstrings(string, ...keys) { for (var key of keys) { if (string.indexOf(key) === -1) { return false; } } return true; } checkSubstrings('this is a string', 'is', 'this'); // true

ناتج هذه الوظيفة هو نفسه السابق. هنا مرة أخرى ، يتم ملء string المعلمات بالمتغير الذي يتم تمريره أولاً ، ولكن يتم وضع باقي المتغيرات في مصفوفة ويتم تخصيصها keys المتغيرات.

يؤدي استخدام المعامل rest بدلاً من الكائن arguments إلى تحسين قابلية قراءة الكود وتجنب مشكلات التحسين في JavaScript. ومع ذلك ، فإن معلمة الراحة لا تخلو من قيودها. على سبيل المثال ، يجب أن تكون الحجة الأخيرة ؛ وإلا سيحدث خطأ في بناء الجملة:

 function logArguments(a, ...params, b) { console.log(a, params, b); } logArguments(5, 10, 15); // SyntaxError: parameter after rest parameter

قيد آخر هو أنه يُسمح بمعامل راحة واحد فقط في إعلان function :

 function logArguments(...param1, ...param2) { } logArguments(5, 10, 15); // SyntaxError: parameter after rest parameter

باقي معلمات دعم المستعرض

متصفحات سطح المكتب:

كروم ثعلب النار متصفح الانترنت مايكروسوفت إيدج أوبرا سفاري
47 15 - أيد 34 -

متصفحات الجوال:

Chrome لنظام Android فايرفوكس موبايل سفاري موبايل أوبرا موبايل IE موبايل
47 15 - - -

المعلمات الافتراضية

المعلمات الافتراضية في ECMAScript 5

لا يدعم JavaScript المعلمات الافتراضية في ECMAScript 5 ، ولكن هناك حل بديل سهل. باستخدام عامل التشغيل OR ( || ) داخل الوظيفة ، يمكننا بسهولة محاكاة المعلمات الافتراضية في ECMAScript 5. ضع في اعتبارك هذه الوظيفة:

 function foo(param1, param2) { param1 = param1 || 10; param2 = param2 || 10; console.log(param1, param2); } foo(5, 5); // 5 5 foo(5); // 5 10 foo(); // 10 10

تتوقع هذه الوظيفة وسيطتين ، ولكن عندما يتم استدعاؤها بدون وسيطات ، فإنها ستستخدم القيم الافتراضية. داخل الوظيفة ، يتم تعيين الوسيطات المفقودة تلقائيًا إلى undefined ؛ لذلك ، يمكننا اكتشاف هذه الحجج وإعلان القيم الافتراضية لها. لاكتشاف الوسائط المفقودة وتعيين القيم الافتراضية ، نستخدم عامل التشغيل المنطقي OR ( || ). يفحص هذا العامل الوسيطة الأولى: إذا كانت صحيحة ، يعيدها العامل ؛ إذا لم يكن كذلك ، فسيقوم العامل بإرجاع الوسيطة الثانية.

يشيع استخدام هذا النهج في الوظائف ، لكن به عيب. سيؤدي تمرير القيمة 0 أو القيمة null إلى تشغيل قيمة افتراضية أيضًا ، لأنها تعتبر قيمًا خاطئة. لذا ، إذا احتجنا بالفعل إلى تمرير 0 أو قيمة null إلى هذه الدالة ، فسنحتاج إلى طريقة بديلة للتحقق مما إذا كانت إحدى المعطيات مفقودة:

 function foo(param1, param2) { if(param1 === undefined){ param1 = 10; } if(param2 === undefined){ param2 = 10; } console.log(param1, param2); } foo(0, null); // 0, null foo(); // 10, 10

داخل هذه الوظيفة ، يتم فحص أنواع الوسائط التي تم تمريرها للتأكد من أنها غير معرفة قبل تعيين القيم الافتراضية. يتطلب هذا الأسلوب رمزًا أكثر قليلاً ، لكنه بديل أكثر أمانًا ويسمح لنا بتمرير 0 و null إلى الوظيفة.

المعلمات الافتراضية في ECMAScript 6

باستخدام ECMAScript 6 ، لم نعد بحاجة إلى التحقق من القيم غير المحددة لمحاكاة المعلمات الافتراضية. يمكننا الآن وضع القيم الافتراضية في إعلان function :

 function foo(a = 10, b = 10) { console.log(a, b); } foo(5); // 5 10 foo(0, null); // 0 null

كما ترى ، يؤدي حذف وسيطة إلى تشغيل القيمة الافتراضية ، لكن تمرير 0 أو لا null لن يؤدي إلى ذلك. يمكننا حتى استخدام الدوال لاسترداد قيم المعلمات الافتراضية:

 function getParam() { alert("getParam was called"); return 3; } function multiply(param1, param2 = getParam()) { return param1 * param2; } multiply(2, 5); // 10 multiply(2); // 6 (also displays an alert dialog)

لاحظ أنه يتم استدعاء دالة getParam فقط إذا تم حذف الوسيطة الثانية. لذلك ، عندما نستدعي وظيفة multiply() بمعاملتين ، فلن يتم عرض التنبيه.

ميزة أخرى مثيرة للاهتمام للمعلمات الافتراضية هي أننا قادرون على الإشارة إلى المعلمات والمتغيرات الأخرى في إعلان function :

 function myFunction(a=10, b=a) { console.log('a = ' + a + '; b = ' + b); } myFunction(); // a=10; b=10 myFunction(22); // a=22; b=22 myFunction(2, 4); // a=2; b=4

يمكنك حتى إجراء عمليات في إعلان function :

 function myFunction(a, b = ++a, c = a*b) { console.log(c); } myFunction(5); // 36

لاحظ أنه على عكس بعض اللغات الأخرى ، تقوم JavaScript بتقييم المعلمات الافتراضية في وقت الاتصال:

 function add(value, array = []) { array.push(value); return array; } add(5); // [5] add(6); // [6], not [5, 6]

دعم متصفح المعلمة الافتراضية

متصفحات سطح المكتب:

ميزة كروم ثعلب النار متصفح الانترنت مايكروسوفت إيدج أوبرا سفاري
الدعم الأساسي 49 15 - 14 - -
معلمات بدون القيم الافتراضية بعد المعلمة الافتراضية 49 26 - 14 - -

متصفحات الجوال:

ميزة Chrome لنظام Android فايرفوكس موبايل سفاري موبايل أوبرا موبايل IE موبايل
الدعم الأساسي 49 15 - - -
معلمات بدون القيم الافتراضية بعد المعلمة الافتراضية 46 26 - - -

التدمير

التدمير هو ميزة جديدة في ECMAScript 6 تمكننا من استخراج القيم من المصفوفات والعناصر وتعيينها إلى متغيرات باستخدام صيغة مشابهة للكائنات والمصفوفات الحرفية. بناء الجملة واضح وسهل الفهم ومفيد بشكل خاص عند تمرير الوسائط إلى وظيفة.

في ECMAScript 5 ، غالبًا ما يتم استخدام كائن التكوين للتعامل مع عدد كبير من المعلمات الاختيارية ، خاصةً عندما لا يكون ترتيب الخصائص مهمًا. ضع في اعتبارك هذه الوظيفة:

 function initiateTransfer(options) { var protocol = options.protocol, port = options.port, delay = options.delay, retries = options.retries, timeout = options.timeout, log = options.log; // code to initiate transfer } options = { protocol: 'http', port: 800, delay: 150, retries: 10, timeout: 500, log: true }; initiateTransfer(options);

يتم استخدام هذا النمط بشكل شائع من قبل مطوري JavaScript ، وهو يعمل بشكل جيد ، ولكن علينا أن ننظر داخل جسم function لمعرفة المعلمات التي يتوقعها. باستخدام المعلمات المدمرة ، يمكننا الإشارة بوضوح إلى المعلمات في إعلان function :

 function initiateTransfer({protocol, port, delay, retries, timeout, log}) { // code to initiate transfer }; var options = { protocol: 'http', port: 800, delay: 150, retries: 10, timeout: 500, log: true } initiateTransfer(options);

في هذه الوظيفة ، استخدمنا نمط إتلاف الكائن ، بدلاً من كائن التكوين. هذا يجعل وظيفتنا ليست أكثر إيجازًا فحسب ، بل تجعلها أسهل في القراءة.

يمكننا أيضًا دمج المعلمات المدمرة مع المعلمات العادية:

 function initiateTransfer(param1, {protocol, port, delay, retries, timeout, log}) { // code to initiate transfer } initiateTransfer('some value', options);

لاحظ أنه سيتم طرح خطأ في النوع إذا تم حذف المعلمات في استدعاء function :

 function initiateTransfer({protocol, port, delay, retries, timeout, log}) { // code to initiate transfer } initiateTransfer(); // TypeError: Cannot match against 'undefined' or 'null'

هذا هو السلوك المطلوب عندما نحتاج إلى معلمات مطلوبة ، ولكن ماذا لو أردنا أن تكون اختيارية؟ لمنع حدوث هذا الخطأ عندما تكون المعلمات مفقودة ، نحتاج إلى تعيين قيمة افتراضية للمعلمات المدمرة:

 function initiateTransfer({protocol, port, delay, retries, timeout, log} = {}) { // code to initiate transfer } initiateTransfer(); // no error

في هذه الوظيفة ، يتم توفير كائن فارغ كقيمة افتراضية للمعلمات المدمرة. الآن ، إذا تم استدعاء هذه الوظيفة بدون أي معلمات ، فلن يحدث أي خطأ.

يمكننا أيضًا تعيين قيمة افتراضية لكل معلمة مدمرة:

 function initiateTransfer({ protocol = 'http', port = 800, delay = 150, retries = 10, timeout = 500, log = true }) { // code to initiate transfer }

في هذا المثال ، تحتوي كل خاصية على معلمة افتراضية ، مما يلغي الحاجة إلينا للتحقق يدويًا من المعلمات غير المحددة وتعيين القيم الافتراضية داخل جسم function .

تدمير دعم المستعرض

متصفحات سطح المكتب:

ميزة كروم ثعلب النار متصفح الانترنت مايكروسوفت إيدج أوبرا سفاري
الدعم الأساسي 49 2.0 - 14 - 7.1
معلمة مدمرة مع تعيين القيمة الافتراضية 49 47 - 14 - -

متصفحات الجوال:

ميزة Chrome لنظام Android فايرفوكس موبايل سفاري موبايل أوبرا موبايل IE موبايل
الدعم الأساسي 49 1 8 - -
معلمات بدون القيم الافتراضية بعد المعلمة الافتراضية 49 47 - - -

الحجج العابرة

هناك طريقتان لتمرير الوسيطات إلى دالة: بالإشارة أو بالقيمة. ينعكس تعديل الوسيطة التي تم تمريرها من خلال المرجع بشكل عام ، ولكن تعديل الوسيطة التي تم تمريرها من خلال القيمة ينعكس فقط داخل الدالة.

في بعض اللغات ، مثل Visual Basic و PowerShell ، لدينا خيار تحديد ما إذا كان يجب تمرير وسيطة بالإشارة أو بالقيمة ، ولكن هذا ليس هو الحال مع JavaScript.

تمرير الحجج بالقيمة

من الناحية الفنية ، يمكن لـ JavaScript المرور بالقيمة فقط. عندما نقوم بتمرير وسيطة إلى دالة بالقيمة ، يتم إنشاء نسخة من تلك القيمة داخل نطاق function . وبالتالي ، فإن أي تغييرات في القيمة تنعكس فقط داخل function . ضع في اعتبارك هذا المثال:

 var a = 5; function increment(a) { a = ++a; console.log(a); } increment(a); // 6 console.log(a); // 5

هنا ، لا يؤثر تعديل الوسيطة داخل الدالة على القيمة الأصلية. لذلك ، عند تسجيل المتغير من خارج الدالة ، تظل القيمة المطبوعة 5 .

تمرير الحجج عن طريق المرجع

في JavaScript ، يتم تمرير كل شيء بالقيمة ، ولكن عندما نمرر متغيرًا يشير إلى كائن (بما في ذلك المصفوفات) ، فإن "القيمة" هي إشارة إلى الكائن ، ويؤدي تغيير خاصية كائن مشار إليه بواسطة متغير إلى تغيير الكائن الأساسي.

ضع في اعتبارك هذه الوظيفة:

 function foo(param){ param.bar = 'new value'; } obj = { bar : 'value' } console.log(obj.bar); // value foo(obj); console.log(obj.bar); // new value

كما ترى ، يتم تعديل خاصية الكائن داخل الوظيفة ، لكن القيمة المعدلة تكون مرئية خارج الوظيفة.

عندما نمرر قيمة غير أولية مثل مصفوفة أو كائن ، يتم إنشاء متغير خلف الكواليس يشير إلى موقع الكائن الأصلي في الذاكرة. ثم يتم تمرير هذا المتغير إلى الوظيفة ، وسيؤثر تعديله على الكائن الأصلي.

اكتب معلمات تدقيق ومفقودة أو إضافية

في لغة مكتوبة بشدة ، يتعين علينا تحديد نوع المعلمات في إعلان function ، لكن JavaScript يفتقر إلى هذه الميزة. في JavaScript ، لا يهم نوع البيانات أو عدد الوسائط التي نمررها إلى دالة.

افترض أن لدينا دالة تقبل وسيطة واحدة فقط. عندما نسمي هذه الوظيفة ، فإننا لا نقتصر على تمرير وسيطة واحدة فقط إلى الدالة ؛ نحن أحرار في تمرير حجة أو اثنتين أو أكثر! قد نختار حتى عدم تمرير أي شيء على الإطلاق ، ولن تحدث أخطاء.

يمكن أن يختلف عدد الوسائط والمعلمات بطريقتين:

  • وسيطات أقل من المعلمات .
    ستساوي المعلمات المفقودة undefined .
  • المزيد من الحجج من المعلمات .
    سيتم تجاهل المعلمات الإضافية ولكن يمكن استرجاعها عبر وسيطات متغيرة تشبه المصفوفة الخاصة (سيتم مناقشتها لاحقًا).

الحجج الإلزامية

إذا كانت هناك وسيطة مفقودة في استدعاء function ، فسيتم تعيينها على undefined . يمكننا الاستفادة من هذا السلوك وإلقاء خطأ إذا تم حذف وسيطة:

 function foo(mandatory, optional) { if (mandatory === undefined) { throw new Error('Missing parameter: mandatory'); } }

في ECMAScript 6 ، يمكننا المضي قدمًا في هذا الأمر واستخدام المعلمات الافتراضية لتعيين الوسائط الإلزامية:

 function throwError() { throw new Error('Missing parameter'); } function foo(param1 = throwError(), param2 = throwError()) { // do something } foo(10, 20); // ok foo(10); // Error: missing parameter

كائن الحجج

تمت إضافة دعم معاملات الراحة إلى ECMAScript 4 بهدف استبدال كائن arguments ، لكن ECMAScript 4 لم يؤت ثماره أبدًا. مع إصدار ECMAScript 6 ، يدعم JavaScript الآن المعلمات المتبقية رسميًا. كما أنه ألغى خطة لإسقاط دعم كائن arguments .

إن الكائن arguments هو كائن يشبه المصفوفة وهو متاح في جميع الوظائف. يسمح باسترداد قيم argument التي تم تمريرها إلى الوظيفة بالرقم وليس بالاسم. يسمح لنا الكائن بتمرير أي عدد من الوسائط إلى دالة. ضع في اعتبارك جزء التعليمات البرمجية التالي:

 function checkParams(param1) { console.log(param1); // 2 console.log(arguments[0], arguments[1]); // 2 3 console.log(param1 + arguments[0]); // 2 + 2 } checkParams(2, 3);

تتوقع هذه الوظيفة تلقي وسيطة واحدة فقط. عندما نسميها مع وسيطتين ، يمكن الوصول إلى الوسيطة الأولى في الوظيفة بواسطة المعلمة اسم المعلمة param1 أو وسيطات كائن arguments[0] ، ولكن يمكن الوصول إلى الوسيطة الثانية فقط arguments[1] . لاحظ أيضًا أنه يمكن استخدام كائن arguments جنبًا إلى جنب مع الوسائط المسماة.

يحتوي كائن arguments على إدخال لكل وسيطة تم تمريرها إلى الوظيفة ، ويبدأ فهرس الإدخال الأول عند 0 . إذا أردنا الوصول إلى المزيد من الوسائط في المثال أعلاه ، فسنكتب arguments[2] arguments[3] وما إلى ذلك.

يمكننا أيضًا تخطي إعداد المعلمات المسماة تمامًا واستخدام الكائن arguments :

 function checkParams() { console.log(arguments[1], arguments[0], arguments[2]); } checkParams(2, 4, 6); // 4 2 6

في الواقع ، تعتبر المعلمات المسماة وسيلة راحة وليست ضرورة. وبالمثل ، يمكن استخدام المعامِلات الباقية لعكس الوسيطات التي تم تمريرها:

 function checkParams(...params) { console.log(params[1], params[0], params[2]); // 4 2 6 console.log(arguments[1], arguments[0], arguments[2]); // 4 2 6 } checkParams(2, 4, 6);

الكائن arguments هو كائن يشبه المصفوفة ، لكنه يفتقر إلى طرق المصفوفات مثل slice() و foreach() . من أجل استخدام عمليات مصفوفة على كائن arguments ، يجب أولاً تحويل الكائن إلى مصفوفة حقيقية:

 function sort() { var a = Array.prototype.slice.call(arguments); return a.sort(); } sort(40, 20, 50, 30); // [20, 30, 40, 50]

في هذه الوظيفة ، يتم استخدام Array.prototype.slice.call() كطريقة سريعة لتحويل كائن arguments إلى مصفوفة. بعد ذلك ، تقوم طريقة sort() بفرز عناصر المصفوفة وإرجاعها.

يحتوي ECMAScript 6 على طريقة أكثر وضوحًا. Array.from() ، إضافة جديدة في ECMAScript 6 ، تنشئ مصفوفة جديدة من أي كائن يشبه المصفوفة:

 function sort() { var a = Array.from(arguments); return a.sort(); } sort(40, 20, 50, 30); // [20, 30, 40, 50]

طول الممتلكات

على الرغم من أن كائن الوسيطات ليس مصفوفة من الناحية الفنية ، إلا أنه يحتوي على خاصية length يمكن استخدامها للتحقق من عدد الوسائط التي تم تمريرها إلى دالة:

 function countArguments() { console.log(arguments.length); } countArguments(); // 0 countArguments(10, null, "string"); // 3

باستخدام خاصية length ، يمكننا التحكم بشكل أفضل في عدد الوسائط التي يتم تمريرها إلى دالة. على سبيل المثال ، إذا كانت الوظيفة تتطلب وسيطتين للعمل ، فيمكننا استخدام خاصية length للتحقق من عدد الوسائط التي تم تمريرها ، وإلقاء خطأ إذا كانت أقل من المتوقع:

 function foo(param1, param2) { if (arguments.length < 2) { throw new Error("This function expects at least two arguments"); } else if (arguments.length === 2) { // do something } }

معلمات الراحة عبارة عن مصفوفات ، لذا فهي تمتلك خاصية length . في ECMAScript 6 ، يمكن إعادة كتابة الكود السابق باستخدام معلمات الراحة:

 function foo(...params) { if (params.length < 2) { throw new Error("This function expects at least two arguments"); } else if (params.length === 2) { // do something } }

خصائص كالي والمتصل

تشير خاصية callee إلى الوظيفة التي يتم تشغيلها حاليًا ، ويشير caller إلى الوظيفة التي استدعت الوظيفة الجاري تنفيذها حاليًا. في الوضع المقيد ECMAScript 5 ، يتم إهمال هذه الخصائص ، وتؤدي محاولة الوصول إليها إلى خطأ في النوع.

تعتبر الخاصية arguments.callee مفيدة في الوظائف العودية (الدالة العودية هي دالة عادية تشير إلى نفسها باسمها) ، خاصةً عندما لا يكون اسم الوظيفة متاحًا (دالة مجهولة). نظرًا لأن الوظيفة المجهولة ليس لها اسم ، فإن الطريقة الوحيدة للإشارة إليها هي من خلال arguments.callee .

 var result = (function(n) { if (n <= 1) { return 1; } else { return n * arguments.callee(n - 1); } })(4); // 24

كائن الحجج في أوضاع صارمة وغير صارمة

في الوضع غير المقيد ECMAScript 5 ، يحتوي كائن arguments على ميزة غير عادية: فهو يحافظ على قيمه متزامنة مع قيم المعلمات المسماة المقابلة.

ضع في اعتبارك جزء التعليمات البرمجية التالي:

 function foo(param) { console.log(param === arguments[0]); // true arguments[0] = 500; console.log(param === arguments[0]); // true return param } foo(200); // 500

داخل هذه الوظيفة ، يتم تعيين قيمة جديدة arguments[0] . نظرًا لأن قيم arguments تظل دائمًا متزامنة مع قيم المعلمات المسماة ، فإن التغيير إلى arguments[0] سيغير أيضًا قيمة param . في الواقع ، إنهما يشبهان اسمين مختلفين لنفس المتغير. في الوضع المقيّد ECMAScript 5 ، تمت إزالة هذا السلوك المربك لكائن arguments :

 "use strict"; function foo(param) { console.log(param === arguments[0]); // true arguments[0] = 500; console.log(param === arguments[0]); // false return param } foo(200); // 200

هذه المرة ، تغيير arguments[0] لا يؤثر على param ، والإخراج كما هو متوقع. ناتج هذه الوظيفة في ECMAScript 6 هو نفسه الموجود في الوضع الصارم ECMAScript 5 ، ولكن ضع في اعتبارك أنه عند استخدام القيم الافتراضية في إعلان function ، لا يتأثر كائن arguments :

 function foo(param1, param2 = 10, param3 = 20) { console.log(param1 === arguments[0]); // true console.log(param2 === arguments[1]); // true console.log(param3 === arguments[2]); // false console.log(arguments[2]); // undefined console.log(param3); // 20 } foo('string1', 'string2');

في هذه الوظيفة ، على الرغم من أن param3 لها قيمة افتراضية ، فإنها لا تساوي arguments[2] لأنه يتم تمرير وسيطتين فقط إلى الدالة. بمعنى آخر ، لا يؤثر تعيين القيم الافتراضية على كائن arguments .

خاتمة

أدخل ECMAScript 6 مئات التحسينات الصغيرة والكبيرة على JavaScript. المزيد والمزيد من المطورين يستخدمون ميزات ECMAScript 6 ، وقريبًا ستكون هذه الميزات لا مفر منها. في هذا البرنامج التعليمي ، تعلمنا كيف قام ECMAScript 6 بترقية معالجة المعلمات في JavaScript ، لكننا خدشنا للتو سطح ECMAScript 6. هناك الكثير من الميزات الجديدة والمثيرة للاهتمام للغة تستحق المراجعة.

الروابط

  • جدول توافق ECMAScript 6 ، Juriy Zaytsev
  • “ECMAScript 2015 Language Specification” ECMA International