النظرية بدلاً من الاستدلال: التحسن كمطورين للواجهة الأمامية



أن تصبح مطورًا أفضل للواجهة الأمامية باستخدام الأساسيات بدلاً من الاستدلال

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

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

  • "استخدم $(document).ready(function(){}) لتهيئة الكود على مواقع jQuery"
  • " var self = this البنية ضرورية لاستدعاء طريقة في وظيفة رد الاتصال"
  • "وظائف السهم لا تحتوي على return "

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


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

الحجج للنهج النظري


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

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

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

معايير مستوى مهارة المطور


عند إجراء مقابلة مع مطوري الواجهة الأمامية ، قمنا بتعيين مهمة برمجة لهم ونقول أنهم يتمتعون بحرية استخدام أي مصادر ، سواء كانت Google أو Stack Overflow. بهذه الطريقة ، من السهل تحديد ما إذا كان المطور متمسكًا بالاستدلال أو النظرية.

السابق ، دون استثناء ، نسخ التعليمات البرمجية من أمثلة أكثر أو أقل ملاءمة مع Stack Overflow. فقط عندما لا يعمل الكود كما هو مخطط له ، بدأوا في ضبطه لأنفسهم. غالبا ما يفشلون.

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

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

مثال


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

بمجرد أن يأتي بيل عبر كائن مثل هذا:

 const usersById = { "5": { "id": "5", "name": "Adam", "registered": true }, "27": { "id": "27", "name": "Bobby", "registered": true }, "32": { "id": "32", "name": "Clarence", "registered": false }, "39": { "id": "39", "name": "Danielle", "registered": true }, "42": { "id": "42", "name": "Ekaterina", "registered": false } } 

يمكن لمثل هذا الكائن عرض قائمة المستخدمين وما إذا كانوا قد سجلوا في حدث معين.

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

 const attendees = usersById.filter(user => user.registered); 

وهنا هو ما يحصل:

 TypeError: usersById.filter is not a function 

يعتقد بيل "شيء هراء" لأنه رأى الكود الذي .filter() فيه .filter() كمرشح.

المشكلة هي أن بيل اعتمد على طريقة الكشف عن مجريات الأمور. إنه لا يفهم أن filter هو طريقة معرفة في المصفوفات ، في حين أن usersById كائن عادي لا يحتوي على طريقة filter .

غوغل بيل الخلط " مرشح جافا سكريبت ". يجد العديد من الإشارات إلى المصفوفات ويدرك أنه يحتاج إلى تحويل usersById إلى صفيف. بعد ذلك ، بسؤال " javascript لتحويل كائن إلى صفيف " ، يجد أمثلة باستخدام Object.keys() في Stack Overflow. بعد ذلك ، يحاول:

 const attendees = Object.keys(usersById).filter(user => user.registered); 

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

الحقيقة هي أن Object.keys() يُرجع مفاتيح الكائن ، لكن ليس قيمته. في الواقع ، اسم المتغير الخاص user مضلل بسهولة ، لأنه ليس كائنًا user ، بل معرفًا ، أي سلسلة. نظرًا لأن السمة registered لم يتم تعريفها للسلاسل ، فإن filter يعامل كل إدخال كاذبة ويترك الصفيف فارغًا.

يلقي بيل نظرة فاحصة على إجابات Stack Overflow ويقوم بالتغيير التالي:

 const attendees = Object.keys(usersById).filter(id => usersById[id].registered); 

هذه المرة تكون النتيجة أفضل: ["5", "27", "39"] . لكن بيل أراد الحصول على أشياء زائر ، وليس هويتهم.

لفهم كيفية تصفية الزوار ، يبحث Bill المتضايق عن " مرشح كائن javascript " ، ويفحص نتائج البحث عن Stack Overflow ويجد هذه الإجابة بالشفرة التالية:

 Object.filter = (obj, predicate) => Object.keys(obj) .filter( key => predicate(obj[key]) ) .reduce( (res, key) => (res[key] = obj[key], res), {} ); 

بيل ينسخ هذه الخطوط ويحاول:

 const attendees = Object.filter(usersById, user => user.registered); 

كل شيء يعمل - على الرغم من أنه ليس من الواضح لماذا. مشروع القانون لا يفهم لماذا هناك حاجة reduce وكيفية استخدامها. علاوة على ذلك ، لا يفهم Bill أنه قام للتو بتعريف طريقة جديدة غير قياسية Object الشامل.

لكن بيل لا يهتم - إنه يعمل! العواقب لا تهمه بعد.

ماذا فعل بيل خطأ؟


جرب بيل طريقة إرشادية لحل المشكلة وواجه المشاكل التالية:

  1. باستخدام .filter() على متغير ، حصل Bill على TypeError . لم يفهم أن filter محدد في الأشياء العادية.
  2. لقد استخدم Object.keys() "لتحويل الكائن إلى صفيف" ، لكن هذا وحده لم يأت بأي نتائج. كان يحتاج إلى إنشاء مجموعة من قيم الكائنات.
  3. حتى بعد استلام القيم واستخدامها كشرط للتصفية ، لم يتلق سوى معرفات فقط بدلاً من كائنات المستخدم المرتبطة بهذه المعرفات. وذلك لأن الصفيف الذي تمت تصفيته يحتوي على معرف ، وليس كائنات المستخدم.
  4. بمرور الوقت ، تخلى بيل عن هذا النهج ووجد حلاً فعالاً على الإنترنت. ومع ذلك ، ما زال لم يفهم كيف يعمل - ولن يضيع الوقت في حلها ، لأنه لديه أشياء أخرى للقيام بها.

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

دعنا ننتقل إلى الأساسيات


إذا كان بيل من دعاة النهج النظري ، فستبدو العملية كما يلي:

  1. لتحديد بيانات الإدخال المحددة وتحديد المخرجات المرغوبة - بمعنى خصائصها: "لدي كائن مفاتيحه عبارة عن سلاسل تمثل المعرّف ، والقيم عبارة عن كائنات تمثل المستخدمين. أريد الحصول على صفيف ستكون قيمه كائنات المستخدم - ولكن فقط كائنات المستخدمين المسجلين "
  2. لفهم كيفية البحث داخل كائن: "أعرف أنه يمكنني الحصول على مجموعة من المفاتيح في كائن عن طريق استدعاء Object.keys() . أريد الحصول على مجموعة لأن المصفوفات تدعم التعداد . "
  3. لكي تدرك أن هذه الطريقة تساعد في الحصول على المفاتيح ، وتحتاج إلى تحويل المفاتيح إلى قيم ، وتذكر map - طريقة واضحة لإنشاء صفيف جديد عن طريق تحويل قيم صفيف آخر:

     Object.keys(usersById).map(id => usersById[id]) 
  4. لمعرفة أن لديك الآن مجموعة من كائنات المستخدم التي يمكن تصفيتها والتي تحتوي على قيم حقيقية تريد تصفيتها:

     Object.keys(usersById).map(id => usersById[id]).filter(user => user.registered) 

اذهب بيل بهذه الطريقة ، يمكنه العمل من أجلنا.

لماذا لا يلجأ الناس إلى النظرية في كثير من الأحيان؟


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

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

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

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


All Articles