فجأة، أليست أساليب روبي سهلة الاستخدام؟ عند كتابة التعليمات البرمجية، فإنه يسرد جميع الأساليب والخصائص المتاحة لكائن ما ويسمح لك بالبحث فيها، وهو أمر مفيد جدًا لتصحيح الأخطاء.
إلى جانب ذلك، فهو فعال أيضًا في التحقق من الأساليب الخاصة بأطر العمل مثل Rails، والمساعدة في قراءة التعليمات البرمجية وفهم المكتبات. على الرغم من أنه من الممارسات الجيدة الرجوع إلى الوثائق الرسمية أو الكود المصدري، فإن طريقة الأساليب مفيدة جدًا للمكتبات حيث لا تحتاج إلى الغوص بعمق أو عندما تكون لديك ذكريات غامضة عن أسماء الطرق.
لتقديم طريقة مختصرة لطرق روبي، يبدو الأمر كما يلي:
الكائن # الطريقة
إرجاع قائمة بأسماء الطرق العامة والمحمية للكائن. سيشمل هذا جميع الأساليب المتاحة في أسلاف obj. إذا كانت المعلمة الاختيارية خاطئة، فإنها تُرجع مصفوفة من الأساليب المفردة العامة والمحمية لـ obj، ولن تتضمن المصفوفة أساليب في الوحدات المضمنة في obj.
بمعنى آخر، تقوم بإرجاع كائن مصفوفة من الخصائص والأساليب التي يمكن الوصول إليها من جهاز الاستقبال.
يتم تنفيذ هذه الطريقة في فئة الكائن، وهي سلف جميع الفئات التي ترث من الكائن، لذلك يمكن استخدامها في أي فئة ترث من الكائن.
نموذج التعليمات البرمجية
class Hoge attr_accessor :fuga def bar puts '' end end puts Hoge.new.methods // => [:bar, :fuga=, :fuga, :hash, :singleton_class, :dup, ...] puts Hoge.new.grep /fuga/ // => [:fuga=, :fuga]
كما هو موضح في المثال، فإنه يُرجع كائن Array، لذا يمكنك أيضًا البحث في قائمة الأساليب باستخدام الأسلوب grep، وهو مناسب جدًا.
لذلك، فكرت فيما إذا كان من الممكن القيام بذلك في JS وقمت بتجربته.
أدناه هو الرمز الفعلي.
يمكن أن يكون اسم الفئة أي شيء، لكنني سأسميها PropertyFinder في الوقت الحالي.
class PropertyFinder { constructor(receiver) { this.receiver = receiver } grep(regexp, options = {}) { let res = [] if (typeof regexp === 'string') { return this.find((name) => name.includes(regexp)) } if (regexp instanceof RegExp) { return this.find((name) => regexp.test(name)) } return [] } toString() { return this.find(() => true) } find(detect) { const list = Object.getOwnPropertyNames(this.receiver).filter(it => detect(it)) if (!this.receiver.__proto__) { return list } const ancestors = new PropertyFinder(this.receiver.__proto__).find(detect) return [...list, ...ancestors] } }
سأشرح الكود لاحقًا، لكن لنبدأ بكيفية استخدامه.
بمجرد تعريف الفئة، يمكنك إضافة طريقة إلى خصائص فئة الكائن على النحو التالي:
Object.prototype.methods = function () { return new PropertyFinder(this) }
من خلال القيام بذلك، يمكنك استخدام طريقة الأساليب في مثيلات الفئات الموروثة من الكائن. ومع ذلك، يرجى العلم بملاحظة التحذير أدناه واستخدامها على مسؤوليتك الخاصة.
إليك بعض أمثلة عمليات التنفيذ:
class Hoge { fuga() { console.log('fuga') } } console.log(new Object().methods().toString()) // => ['constructor', 'constructor', '__defineGetter__', '__defineSetter__', 'hasOwnProperty' ...] console.log([].methods().toString()) // => ['length', 'length', 'constructor', 'at', 'concat', ...] console.log(new Hoge().methods().grep(/fuga/) // => ['fuga']
*لا ينصح باستخدام هذا الرمز في بيئات الإنتاج *
تعد إضافة خصائص إلى فئات ذات مستوى أعلى من خلال تصحيح القرود بمثابة نمط مضاد وقد يؤدي إلى مشاكل في التغييرات المستقبلية في مواصفات JS. استخدمه بحذر وعلى مسؤوليتك الخاصة.
المرجع: سلبيات الترقيع القرد
الآن، دعنا ننتقل إلى شرح الكود.
الطريقة الأكثر أهمية في PropertyFinder هي طريقة البحث. تجتاز هذه الطريقة سلسلة النموذج الأولي للكائن المحدد، وتبحث عن خصائص يمكن الوصول إليها، وترجعها كقائمة.
تستخدم أساليب toString وgrep ببساطة البحث، لذلك لا تحتاج إلى مزيد من التوضيح.
قد تكون سلسلة النموذج الأولي غير مألوفة للبعض، ولكنها وراثة الخصائص من فئة الكائن.
الميراث والسلسلة النموذجية | شبكة مزاد موزّعة
تم تغطية التفاصيل في وثائق MDN، ولكن آلية وراثة JavaScript مدعومة من خلال سلسلة النموذج الأولي.
على الرغم من أن الأمر ليس واضحًا دائمًا، إلا أنه عند الإشارة إلى بعض الخصائص، فإن العملية تتضمن:
تستمر هذه العملية حتى يتم العثور على تطابق، ثم يتم إرجاعه.
نظرًا لما ورد أعلاه، تطبق طريقة البحث في PropertyFinder هذه الآلية، مما يسمح لك بالحصول على قائمة بالخصائص من خلال استكشاف __proto__ بشكل متكرر.
إليك التنفيذ الذي يحقق ذلك من خلال استكشاف __proto__ بشكل متكرر للحصول على القائمة:
find(detect) { const list = Object.getOwnPropertyNames(this.receiver).filter(it => detect(it)) if (!this.receiver.__proto__) { return list } const ancestors = new PropertyFinder(this.receiver.__proto__).find(detect) return [...list, ...ancestors] }
وبهذا ينتهي شرح PropertyFinder.
وبهذا ينتهي شرح الكود وما قمت بتجربته.
كان هذا مجرد تمرين تجريبي أو مرح، ولكن نظرًا لأنه يتضمن بعض المعرفة والتقنيات، أتمنى أن تجده مفيدًا أو ملهمًا لتطبيقاتك الخاصة.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3