البرمجة الوظيفية من وجهة نظر EcmaScript. وظائف نقية ، lambdas ، الحصانة

مرحبا يا هبر!

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

مقدمة في البرمجة الوظيفية


البرمجة الوظيفية (FP) هي وسيلة لتنظيم التعليمات البرمجية عن طريق كتابة مجموعة من الوظائف.

EcmaScript ، كونها لغة برمجة متعددة النماذج ، تنفذ ، من بين أمور أخرى ، نموذجًا وظيفيًا. هذا يعني أن الوظائف في ES هي بيانات ويمكن نقلها إلى وظائف ، وإرجاعها من وظائف ، ويمكنها قبول الوظائف بنفسها. أي وظائف في ES هي وظائف من الدرجة الأولى .

تتبع التعريفات التالية من هذا:

الوسيطة الوظيفية (funarg) - الوسيطة التي تكون قيمتها دالة.

دالة الترتيب العالي (FWP ، ترتيب الوظائف العالي ، hof) هي وظيفة تقبل الدالات كوسائط.

وظائف ذات قيمة وظيفية (وظائف قيمة الوظيفة) - دالة تقوم بإرجاع دالة.

يتم دمج كل هذه الأنواع من الوظائف بشكل مشروط في وظائف من الدرجة الأولى ، وعلى النحو التالي من التعريف أعلاه ، في جميع وظائف ES هي كائنات من الدرجة الأولى.

وظائف نقية - مثالية للبرمجة الوظيفية


الوظائف الخالصة (PF) - تُرجع دائمًا نتيجة متوقعة.
خصائص PF:

  • تعتمد نتيجة تنفيذ PF فقط على الوسائط التي تم تمريرها والخوارزمية التي تنفذ PF
  • لا تستخدم القيم العالمية
  • لا تقم بتعديل القيم الخارجية أو الوسيطات التي تم تمريرها
  • لا تكتب البيانات إلى الملفات أو قواعد البيانات أو أي مكان آخر

مثال على وظيفة نقية:

const add = (x,y) => x+y; 

مثال جيد على وظيفة النجاسة هو:

 var first; var second; function testFn() { var a = 10; first = function() { return ++a; } second = function() { return --a; } a = 2; first();//3 } testFn(); first();//4 second();//3 

تخيل مدى تعقيد كتابة اختبارات لهذا المثال ومدى تبسيطها للوظائف الخالصة!

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

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

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

لامدا - وظائف


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

ظهر مصطلح لامدا حساب التفاضل والتكامل في الثلاثينيات من قبل كنيسة ألونزو. في جوهرها ، حساب التفاضل والتكامل lambda ليس أكثر من شكل رسمي لوصف المعادلة الرياضية. مزيد من التفاصيل هنا .

في ES ، تنفذ وظيفة lambda غالبًا عملية إغلاق:

 const add = x => y => x + y; 

قصيرة وموجزة. وظيفة الإضافة هي lambda تأخذ وسيطة x ، وتقوم بتخزينها في الإغلاق ، وتقوم بإرجاع دالة.

قارن مع هذا الكود:

 funtion add(x) { return function (y) { return x + y; } } 

من الواضح أن الخيار الأول يبدو أفضل.

Imutabelnost


غير قابل للتغيير (غير قابل للتغيير ، المناعة) هو كائن لا يمكن تغيير حالته بعد الخلق. ستكون نتيجة أي تعديل لهذا الكائن دائمًا كائنًا جديدًا ، بينما لن يتغير الكائن القديم.

الثبات هو الكأس الذهبي للبرمجة الوظيفية.

النظر في مثال:

 const impureAddProp = (key, value, object) => { object[key] = value;//   }; const User= { name: 'Alex' }; impureAddProp ('isAdmin', true, User); 

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

من وجهة نظر البرمجة الوظيفية ، سيكون من الصحيح:

 const pureAddProp = (key, value, object) => ({ ...object, [key]: value }); const User= { name: 'Alex' }; const Admin= pureAddProp ('isAdmin', true, User); 

لذلك سيبقى كائن المستخدم بدون تغيير. نحن نقوم بتعديل نسخة من البيانات ، والتي تكون آمنة دائمًا.

استنتاج


لقد درسنا اليوم العديد من المفاهيم النظرية الهامة. تعرفنا على وظائف نقية وشكل لامدا من وظائف التسجيل ومفهوم الثبات في fp. ومع ذلك ، هذا المقال هو نوع من المقدمة. ستكون الأفكار والتقنيات الرئيسية و "الأجزاء الصلبة" للبرمجة الوظيفية في المقالات التالية.

يتم تنفيذ البرمجة الوظيفية بواسطة العديد من المكتبات. هذا هو رامدا ، و lodash ، وغيرها الكثير. في مشروع حقيقي ، بالطبع ، سوف تستخدمها. تحت غطاء أي مكتبة ، سيظل هناك نفس جافا سكريبت الأصلي ، لذلك في المقالات التالية سوف نقوم بتحليل FP ، وتنفيذ جميع مفاهيمها على JS الأصلي.

حاشية


بدأت في كتابة المقالات ، وقد وضعت في اعتباري الخطة التالية:

  • اكتب ترجمات لمقالات مثيرة للاهتمام باللغة الإنجليزية
  • لتسليط الضوء على العديد من المجالات ذات الصلة في JS (المفاهيم الأساسية ، OOP من حيث مواصفات EcmaScript ، والأنماط ، والبرمجة الوظيفية).

حتى الآن ، تمت كتابة المقالات الرئيسية في ثلاثة مجالات:

  1. هذا و ScopeChain في EcmaScript - هنا وصفت مفاهيم رئيسية من المواصفات مثل سياق التنفيذ ، هذه الكلمة الأساسية ، وخاصية سياق ScopeChain (سلسلة النطاق). في إطار هذا الاتجاه ، تم نشر مقالتي حول البيئة المعجمية والإغلاق حرفيًا اليوم.
  2. نظرة من EcmaScript على النظرية العامة لـ OOP - تم توضيح الفرق بين كتابة الفصل الثابت وتنظيم النموذج الديناميكي هنا ، وتفكيك نموذج التفويض وكتابة البط
  3. الأنماط الأنيقة في جافا سكريبت الحديثة (سلسلة ترجمة بيل سورور على الدورة) - إليك نموذجان يمكن أن يكونا مفيدين في بعض الحالات. نهجي من حيث الأنماط بسيط للغاية: من الأفضل معرفة أكبر عدد ممكن من الأنماط ، لأنه عاجلا أم آجلا تأتي في متناول اليدين

والآن حان دور البرمجة الوظيفية. في المستقبل ، سأكتب مقالات في استمرار كل من هذه المجالات. على سبيل المثال ، سوف تتناول المقالة التالية المفاهيم الأساسية لـ OOP: التغليف ، والتجريد ، والشوائب (والسكتات الدماغية) ، والواجهات ، وما إلى ذلك ... وأخطط أيضًا للحديث عن كيفية تنفيذ OOP في ES تحت غطاء المحرك ، أي حول خصائص [[Prototype]] و [[Class]] وأكثر من ذلك بكثير. تحدث عن كيفية قيام الإصدار الثامن بإنشاء كيانات وحالات للفئات والوظائف.

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

في المقالات ، إما أن أقوم بمراجعة المفاهيم ، وأقول كيف يتم ترتيبها تحت الغطاء (في رأيي ، هذا يحسن فهم ما نكتبه ولماذا نكتب بهذه الطريقة) ، أو أتحدث عن بعض الأشياء التي توسع آفاقي. في رأيي هذا مهم جدا. ألقِ نظرة على شركات مثل Yandex أو Edadil ، وهم يتحدثون باستمرار عن نوع من الأفكار الأصلية. إما أن تكون هذه الصور النقطية في رد فعل ، ثم تطبيق vue بالكامل تقريباً على فئات es6. معظم مطوري الويب لم يفكروا أبدًا في مثل هذا الشيء. هذا يتطلب نظرة واسعة.

أنا شخصياً درست ودرست الويب بهذه الطريقة ، أي بعد قراءة برنامج تعليمي أو رصيف ، أحاول أن أفهم كيف تعمل الأداة الموصوفة تحت الغطاء ، لفهم آلياتها الداخلية.

حتى المقالات في المستقبل ، والأصدقاء!

Source: https://habr.com/ru/post/ar474702/


All Articles