معامل بدون هدية؟ نفهم المعاملات الافتراضية في JavaScript
\n\nتخيل أنك طلبت بيتزا. تتصل بخدمة التوصيل وتقول: «من فضلك، بيتزا». يسأل الموظف: «أي نوع؟» — «المعتادة، بالجبن والنقانق». أنت لا تفكر حتى في أن البيتزا لها معاملات افتراضية.
\n\nنفس الشيء في JavaScript: غالبًا ما تُستدعى الدوال بدون جميع الوسائط. وإذا لم يقم المبرمج بتوفير set a default parameter value for a JavaScript function، فقد يتعطل الكود أو يتصرف بشكل غير متوقع. في هذه المقالة، سنشرح جميع الطرق لتعيين قيمة افتراضية لمعامل دالة في JS — من الحلول القديمة الجيدة إلى الصياغة الحديثة في ES6. هيا بنا!
\n\nلماذا هذا مهم أصلاً؟
\n\nلنفترض أن لدينا دالة ترحب بالمستخدم:
\n\nfunction greet(name) {\n console.log('مرحبًا، ' + name + '!');\n}\n\ngreet(); // ستطبع: "مرحبًا، undefined!" — محرج، أليس كذلك؟\n\nبدون default parameters javascript، تصبح الوسيطة غير المُرسلة undefined. وإذا حاولنا استدعاء دالة على undefined — سنحصل على خطأ. لذلك، المعاملات الافتراضية js ليست مجرد راحة، بل حماية من الأخطاء.
الطريقة 1: الكلاسيكية — العامل الثلاثي (أو if)
\n\nقبل ظهور ES6، كان المطورون يستخدمون العامل الثلاثي في javascript أو فحصًا بسيطًا. هذا يعمل، لكنه يبدو ضخمًا:
\n\nfunction multiply(a, b) {\n a = a !== undefined ? a : 1;\n b = b !== undefined ? b : 2;\n return a * b;\n}\n\nconsole.log(multiply(5)); // 10 (5 * 2)\nconsole.log(multiply()); // 2 (1 * 2)\n\nالإيجابيات: واضح حتى للمبتدئين، متوافق مع المتصفحات القديمة.
\nالسلبيات: الكود يصبح متضخمًا. إذا كان هناك 5-6 معاملات، تقل قابلية القراءة بشكل كبير.
حجر العثرة: الفحص على undefined مقابل truthy
\n\nيكتب العديد من المبتدئين هكذا:
\n\nfunction greet(name) {\n name = name || 'ضيف';\n console.log('مرحبًا، ' + name);\n}\n\nهذا يعمل طالما لم ترسل 0، أو سلسلة فارغة ''، أو false. كل هذه القيم هي falsy، وستستبدلها الدالة بـ 'ضيف'. إذا كنت بحاجة لإرسال 0 كقيمة صالحة — فهذه الطريقة ستفشل. استخدم الفحص الصارم على undefined.
الطريقة 2: الكائن السحري arguments
\n\nداخل كل دالة (باستثناء الدوال السهمية) يوجد كائن ضمني يشبه المصفوفة يسمى arguments javascript. يمكن استخدامه للتحقق من الوسائط المُرسلة:
\n\nfunction showInfo(name, age) {\n name = arguments.length > 0 ? name : 'مجهول';\n age = arguments.length > 1 ? age : 'غير محدد';\n return `${name}, العمر: ${age}`;\n}\n\nconsole.log(showInfo()); // مجهول, العمر: غير محدد\n\nالإيجابيات: يعطي تحكمًا كاملاً في الوسائط المُرسلة.
\nالسلبيات: الصياغة قديمة، لا تعمل في الدوال السهمية. تُستخدم عادةً فقط لمهام محددة جدًا (مثل عندما يكون عدد المعاملات غير معروف مسبقًا).
الطريقة 3: المعيار الحديث — المعاملات الافتراضية في ES6
\n\nبدءًا من ECMAScript 2015، يمكن تعيين المعاملات الافتراضية js مباشرة في تعريف الدالة. هذه هي أنظف وأفضل طريقة موصى بها:
\n\nfunction multiply(a = 1, b = 2) {\n return a * b;\n}\n\nconsole.log(multiply(5)); // 10\nconsole.log(multiply()); // 2\n\nجميل، أليس كذلك؟ لكن هناك تفاصيل دقيقة مهمة يجب معرفتها لتجنب الوقوع في الفخ.
\n\nالتفصيل 1: القيم الافتراضية تُحسب عند الاستدعاء
\n\nهذا يعني أنه إذا أرسلت undefined — فسيتم تفعيل القيمة الافتراضية. إذا أرسلت null — لا:
function test(x = 10) {