0Pricing
JavaScript Academy · درس

تحويل الدوال إلى دوال متسلسلة

حوّلوا الدوال متعددة الوسائط إلى سلاسل من الاستدعاءات.

تحويل الدوال إلى دوال متسلسلة درس مجاني في JavaScript Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في JavaScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة JavaScript Academy 4 دروس في المجموع.

ما التكاري

يحوّل التكاري دالة تتلقى عدة معاملات إلى سلسلة من الدوال، تتلقى كل واحدة منها معاملًا واحدًا.

فبدلًا من استدعاء add(1, 2, 3)، تستدعون add(1)(2)(3). ويُعيد كل استدعاء الدالة التالية حتى تُجمَع جميع المعاملات.

التكاري يدويًا

أوضح طريقة لفهم التكاري هي كتابة دوال متداخلة، تُعيد كل واحدة منها التالية وتغلق على المعاملات السابقة.

function add(a) {
  return function (b) {
    return function (c) {
      return a + b + c;
    };
  };
}

console.log(add(1)(2)(3));

إعادات الأسهم المتداخلة

تجعل دوال الأسهم التعريفات التكارية أقصر. يعيد كل => سهمًا تاليًا، بينما ينفذ السهم الأخير العمل.

const add = a => b => c => a + b + c;

console.log(add(1)(2)(3));
console.log(add(10)(20)(30));

الإغلاقات تتذكر المعاملات

يعتمد التكاري على الإغلاقات. تحتفظ كل دالة مُعادة بمرجع إلى المتغيرات من نطاقها الخارجي، لذلك تظل المعاملات السابقة متاحة حتى تنفيذ الاستدعاء الأخير.

const greet = greeting => name => greeting + ', ' + name + '!';

const sayHi = greet('Hi');
console.log(sayHi('Ada'));
console.log(sayHi('Grace'));

الاستدعاء خطوة بخطوة

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

const add = a => b => c => a + b + c;

const addOne = add(1);
const addOneAndTwo = addOne(2);

console.log(addOneAndTwo(3));
console.log(addOneAndTwo(100));

مساعد curry عام

تُعد كتابة الدوال المتداخلة يدويًا أمرًا مملًا. يجمع مساعد curry العام المعاملات حتى يحصل على العدد الكافي، ثم يستدعي الدالة الأصلية.

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn(...args);
    }
    return (...more) => curried(...args, ...more);
  };
}

const add = curry((a, b, c) => a + b + c);
console.log(add(1)(2)(3));

استدعاء مرن باستخدام curry

يقبل مساعد curry الجيد الوسائط بأي تجميع. وتخبره fn.length بعدد المعاملات التي أعلنت عنها الدالة الأصلية.

function curry(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn(...args);
    }
    return (...more) => curried(...args, ...more);
  };
}

const add = curry((a, b, c) => a + b + c);
console.log(add(1, 2, 3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));

استخدام Currying للتخصيص

يجعل Currying التخصيص أمرًا طبيعيًا: طبّق الوسيط الأول، ثم أعد استخدام الدالة الناتجة عبر العديد من الاستدعاءات.

const multiply = a => b => a * b;

const double = multiply(2);
const triple = multiply(3);

console.log(double(5));
console.log(triple(5));

استخدام Currying مع أساليب المصفوفات

تتوافق الدوال المطبَّقة بأسلوب Currying تمامًا مع map وfilter، لأن كل واحدة منها تنتج دالة ذات وسيط واحد جاهزة لتلقي كل عنصر.

const greaterThan = min => value => value > min;

const over10 = greaterThan(10);
console.log([5, 12, 8, 20].filter(over10));

Currying والتطبيق الجزئي

يثبّت التطبيق الجزئي بعض الوسائط ويترك الباقي لاستدعاء واحد لاحق. أما Currying فيحوّل الدالة دائمًا إلى سلسلة من الاستدعاءات ذات الوسيط الواحد.

يُعد Currying شكلًا محددًا ومفككًا بالكامل من التطبيق الجزئي.

const partial = (a, b) => c => a + b + c;
const curried = a => b => c => a + b + c;

console.log(partial(1, 2)(3));
console.log(curried(1)(2)(3));

لماذا نستخدم Currying؟

يشجّع Currying على إنشاء دوال صغيرة قابلة للتركيب وإعادة الاستخدام. وهو يتكامل طبيعيًا مع تركيب الدوال، الذي ستستكشفه بعد ذلك. والفكرة الأساسية هي أن الدالة المطبَّقة بأسلوب Currying لا تكون «غير مكتملة» أبدًا؛ بل تُعيد دالة أخرى إلى أن تحصل على الوسائط المطلوبة.

const tag = name => content => '<' + name + '>' + content + '</' + name + '>';

const bold = tag('b');
console.log(bold('important'));
console.log(tag('i')('slanted'));

اختبار سريع

إذا كانت لدينا const add = a => b => c => a + b + c;، فما الناتج الذي تُقيَّم إليه add(1)(2)؟

مراجعة: Currying

لقد تعلمت تفكيك الدوال إلى سلاسل من الاستدعاءات ذات الوسيط الواحد:

  • تُعيد الدوال المطبَّقة بأسلوب Currying دالة جديدة لكل وسيط باستخدام الإغلاقات.
  • توفّر الدوال السهمية المتداخلة تعريفات مختصرة للدوال المطبَّقة بأسلوب Currying.
  • يستخدم مساعد curry العام fn.length لمعرفة متى وصلت الوسائط الكافية.
  • يتيح Currying تخصيص الدوال وتركيبها بطريقة واضحة.

الأسئلة الشائعة

هل درس «تحويل الدوال إلى دوال متسلسلة» مجاني؟

نعم — نص درس «تحويل الدوال إلى دوال متسلسلة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة JavaScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة JavaScript Academy 4 دروس في المجموع.

ماذا ستتعلم في «تحويل الدوال إلى دوال متسلسلة»؟

حوّلوا الدوال متعددة الوسائط إلى سلاسل من الاستدعاءات. تتمرن على JavaScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ JavaScript Academy؟

لا تُشترط خبرة سابقة. JavaScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «تحويل الدوال إلى دوال متسلسلة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس JavaScript Academy هذا؟

نعم. كل درس في JavaScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. التطبيق الجزئي
  2. تحويل الدوال إلى دوال متسلسلة
  3. تركيب الدوال
  4. بناء pipe وcompose
← العودة إلى JavaScript Academy