يمكن أن تساعدك ميزة لغة JavaScript هذه في تنظيم التعليمات البرمجية الخاصة بك وستمنحك تقديرًا جديدًا لكيفية عمل الوظائف.
يمكن أن تساعد الوظائف المتقنة في جعل كود JavaScript الخاص بك أكثر قابلية للقراءة والتعبير. تعتبر تقنية الكاري مثالية عندما تريد تقسيم المنطق المعقد إلى أجزاء أصغر ومكتفية بذاتها وأكثر قابلية للإدارة من التعليمات البرمجية.
تعلم كل شيء عن الدوال الكاري في JavaScript، وكيفية استخدام تقنية الكارينج للإنشاء الوظائف المطبقة جزئيًا، بالإضافة إلى حالات الاستخدام الواقعية لكل من الوظائف المعالجة والمطبقة جزئيًا المهام.
ما هو الكاري؟
تم تسمية الكاري على اسم عالم الرياضيات هاسكل ب. كاري، والمفهوم مستمد من حساب التفاضل والتكامل لامدا. يأخذ Currying دالة تستقبل أكثر من معلمة واحدة وتقسمها إلى سلسلة من الوظائف الأحادية (ذات معلمة واحدة). بمعنى آخر، الدالة الكاري تأخذ معلمة واحدة فقط في كل مرة.
مثال أساسي للكاري
فيما يلي مثال على وظيفة الكاري:
functionbuildSandwich(ingredient1) {
return(ingredient2) => {
return(ingredient3) => {
return`${ingredient1},${ingredient2},${ingredient3}`
}
}
}
ال بناء ساندويتش ()
ترجع الدالة دالة أخرى - دالة مجهولة تستقبل المكون2 دعوى. ثم تقوم هذه الدالة المجهولة بإرجاع دالة مجهولة أخرى يتم تلقيها المكون3. أخيرًا، تقوم هذه الوظيفة الأخيرة بإرجاع القالب حرفيًا، بطريقة ما سلاسل التنسيق في جافا سكريبت.ما قمت بإنشائه هو وظيفة متداخلة حيث تقوم كل وظيفة باستدعاء الوظيفة الموجودة أسفلها حتى نصل إلى النهاية. الآن، عندما تتصل بناء ساندويتش () وتمريرها معلمة واحدة، فإنها ستعيد جزء الوظيفة التي لم تقدم وسائطها بعد:
console.log(buildSandwich("Bacon"))
يمكنك أن ترى من خلال الإخراج أن buildSandwich يُرجع دالة:
لإكمال استدعاء الدالة، ستحتاج إلى توفير جميع الوسائط الثلاث:
buildSandwich("Bacon")("Lettuce")("Tomato")
يقوم هذا الكود بتمرير "لحم الخنزير المقدد" إلى الوظيفة الأولى، و"الخس" إلى الوظيفة الثانية، و"الطماطم" إلى الوظيفة الأخيرة. وبعبارة أخرى، بناء ساندويتش () يتم تقسيم الوظيفة فعليًا إلى ثلاث وظائف، حيث تتلقى كل وظيفة معلمة واحدة فقط.
في حين أنه من الصحيح تمامًا استخدام الوظائف التقليدية، إلا أن كل عمليات التداخل يمكن أن تصبح قبيحة جدًا كلما تعمقت. للتغلب على هذه المشكلة، يمكنك استخدام وظائف الأسهم والاستفادة من تركيبها الأنظف:
const buildMeal = ingred1 =>ingred2 =>ingred3 =>
`${ingred1}, ${ingred2}. ${ingred3}`;
هذه النسخة المُعاد هيكلتها أكثر إيجازًا، وهي ميزة للاستخدام وظائف السهم مقابل الوظائف العادية. يمكنك استدعاء الوظيفة بنفس الطريقة التي استخدمتها مع الوظيفة السابقة:
buildMeal("Bacon")("Lettuce")("Tomato")
وظائف الكاري المطبقة جزئيا
الوظائف المطبقة جزئيًا هي الاستخدام الشائع للكاري. تستلزم هذه التقنية توفير الوسائط المطلوبة فقط في كل مرة (بدلاً من توفير كافة الوسائط). عندما تقوم باستدعاء دالة عن طريق تمرير جميع المعلمات المطلوبة، فإنك تقول أنك "طبقت" تلك الوظيفة.
لنلقي نظرة على مثال:
const multiply = (x, y) => x * y;
فيما يلي النسخة الكاري من الضرب:
const curriedMultiply = x =>y => x * y;
ال curriedMultiply() الوظيفة تستقبل س حجة للوظيفة الأولى و ذ بالنسبة للدالة الثانية، فإنه يقوم بضرب القيمتين.
لإنشاء أول دالة مطبقة جزئيًا، اتصل بـ curriedMultiple() باستخدام المعلمة الأولى وتعيين الوظيفة التي تم إرجاعها إلى متغير:
const timesTen = curriedMultiply(10)
في هذه المرحلة، تم تطبيق الكود "جزئيًا" على curriedMultiply() وظيفة. لذلك في أي وقت تريد الاتصال به مرات عشرة ()، كل ما عليك فعله هو تمرير رقم واحد وسيتم ضرب الرقم تلقائيًا في 10 (المخزن داخل الوظيفة المطبقة):
console.log(timesTen(8)) // 80
يتيح لك ذلك البناء على وظيفة معقدة واحدة عن طريق إنشاء وظائف مخصصة متعددة منها، كل منها لها وظائفها الخاصة المقفلة.
ألقِ نظرة على مثال أقرب إلى حالة استخدام حقيقية لتطوير الويب. أدناه لديك تحديثElemText() الدالة التي تأخذ عنصرا بطاقة تعريف في المكالمة الأولى، المحتوى الموجود في المكالمة الثانية، ثم يقوم بتحديث العنصر بناءً على بطاقة تعريف والمحتوى الذي قدمته له:
const updateElemText = id = content
=> document.querySelector(`#${id}`).textContent = content// Lock the element's id into the function:
const updateHeaderText = updateElemText('header')
// Update the header text
updateHeaderText("Hello World!")
تكوين الوظيفة مع وظائف الكاري
الاستخدام الشائع الآخر للكاري هو تكوين الوظيفة. يتيح لك ذلك استدعاء الوظائف الصغيرة، بترتيب معين، ودمجها في وظيفة واحدة أكثر تعقيدًا.
على سبيل المثال، في موقع ويب افتراضي للتجارة الإلكترونية، إليك ثلاث وظائف قد ترغب في تشغيلها واحدة تلو الأخرى (بالترتيب الدقيق):
const addCustomer = fn =>(...args) => {
console.log("Saving customer info")
return fn(...args)
}const processOrder = fn =>(...args) => {
console.log(`processing order #${args[0]}`)
return fn(...args);
}
let completeOrder = (...args) => {
console.log(`Order #${[...args].toString()} completed.`);
}
لاحظ أن هذا الرمز يستخدم يترك الكلمة الأساسية لتحديد اكمل الطلب() وظيفة. يتيح لك هذا إعادة تعيين قيمة للمتغير وهو جزء من كيف يعمل النطاق في جافا سكريبت.
بعد ذلك، تحتاج إلى استدعاء الوظائف بترتيب عكسي (من الداخل إلى الخارج) لأنك تريد إضافة العملاء أولاً:
completeOrder = (processOrder(completeOrder));
completeOrder = (addCustomer(completeOrder));
completeOrder("1000")
سيعطيك هذا الإخراج التالي:
إذا كنت ستكتب الوظائف المذكورة أعلاه بالطريقة العادية، فسيبدو الكود كما يلي:
functionaddCustomer(...args) {
returnfunctionprocessOrder(...args) {
returnfunctioncompleteOrder(...args) {
// end
}
}
}
عندما تتصل ب إضافة العميل () دالة وتمرير الوسيطات، فإنك تبدأ من الداخل وتتجه نحو أعلى الدالة.
تحويل دالة عادية إلى دالة كاري باستخدام دالة كاري
إذا كنت تخطط لاستخدام وظائف الكاري كثيرًا، فيمكنك تبسيط العملية باستخدام وظيفة مساعدة.
ستقوم هذه الوظيفة بتحويل أي وظيفة عادية إلى وظيفة الكاري. يستخدم العودية للتعامل مع أي عدد من الوسائط.
const curry = (fn) => {
return curried = (...args) => {
if (fn.length !== args.length) {
return curried.bind(null, ...args)
}
return fn(...args);
}
}
ستقبل هذه الوظيفة أي دالة مكتوبة قياسية تستقبل أكثر من معلمة واحدة، مما يؤدي إلى إرجاع نسخة منقحة من تلك الوظيفة. لرؤيتها على أرض الواقع، استخدم هذا المثال للدالة التي تأخذ ثلاث معلمات وتجمعها معًا:
const total = (x, y, z) => x + y + z
لتحويل هذه الوظيفة، اتصل بـ كاري() وظيفة وتمرير المجموع كحجة:
const curriedTotal = curry(total)
الآن، لاستدعاء الدالة، تحتاج فقط إلى تمرير كافة الوسائط:
console.log(curriedTotal(10)(20)(30)) // 60
المزيد عن الوظائف في JavaScript
تعتبر وظائف JavaScript مرنة للغاية ووظائف الكاري ليست سوى جزء صغير من ذلك. هناك العديد من أنواع الوظائف الأخرى مثل وظائف الأسهم، والوظائف المنشئة، والوظائف المجهولة. يعد التعرف على هذه الوظائف ومكوناتها أمرًا أساسيًا لإتقان JavaScript.