TypeScript ومُهيئات الحقول: كيف تؤثر تهيئة الحقول على أداء الكود الخاص بك
\n\nتخيل: أنت تكتب فئة (class) في TypeScript، وتُنشئ عدة حقول، وتُسند إليها قيمًا مباشرةً داخل جسم الفئة. كل شيء يعمل، الكود جميل وموجز. لكن هل تساءلت يومًا ما الذي يحدث «تحت الغطاء»؟ اتضح أنه حتى شيء بسيط مثل مُهيئات الحقول (field initializers) يمكن أن يصبح سببًا للصداع إذا لم تفهم كيفية عملها. هذا السؤال هو واحد من أكثر الأسئلة شيوعًا على Stack Overflow مع آلاف المشاهدات. واليوم سنقوم بتحليله مرة واحدة وإلى الأبد.
\n\nفي هذه المقالة، لن نُظهر فقط كيفية كتابة الكود. سننظر داخل محرك TypeScript، ونقارن بين الطرق المختلفة، ونقدم توصيات محددة تجعل كودك أسرع وأنظف. هيا بنا!
\n\nما هي مُهيئات الحقول في TypeScript ولماذا يختلف عليها؟
\n\nمُهيئات الحقول (field initializers) هي سكر نحوي (syntactic sugar) في TypeScript، يسمح لك بتعيين قيم لخصائص الفئة مباشرةً عند تعريفها. بدلاً من كتابة:
\n\nclass User {\n private name: string;\n private age: number;\n \n constructor(name: string, age: number) {\n this.name = name;\n this.age = age;\n }\n}\n\n\nيمكنك الكتابة بشكل أقصر:
\n\nclass User {\n private name: string = 'Default';\n private age: number = 0;\n \n constructor(name: string, age: number) {\n this.name = name;\n this.age = age;\n }\n}\n\n\nللوهلة الأولى، هذا أمر بسيط. لكن على Stack Overflow، تشتعل المناقشات: بعض المطورين يؤكدون أن مُهيئات الحقول تُبطئ التطبيق، بينما يرى آخرون أنها الطريقة الأكثر قابلية للقراءة. من هو على صواب؟ دعنا نكتشف.
\n\nكيف يقوم TypeScript بتجميع مُهيئات الحقول: نظرة تحت الغطاء
\n\nلفهم التأثير على الأداء، نحتاج إلى رؤية ما يتحول إليه الكود الخاص بنا بعد التجميع إلى JavaScript. TypeScript هي طبقة إضافية تُجمّع إلى JS. وكيفية حدوث التجميع تؤثر بشكل مباشر على سرعة العمل.
\n\nلنأخذ فئة بسيطة مع مُهيئ حقل:
\n\nclass Car {\n brand: string = 'Toyota';\n year: number = 2020;\n \n constructor(brand: string, year: number) {\n this.brand = brand;\n this.year = year;\n }\n}\n\n\nبعد التجميع إلى ES6 (JavaScript الحديث)، سنحصل على كود مشابه لهذا:
\n\nclass Car {\n constructor(brand, year) {\n this.brand = 'Toyota'; // مُهيئ الحقل\n this.year = 2020; // مُهيئ الحقل\n this.brand = brand; // المُنشئ\n this.year = year; // المُنشئ\n }\n}\n\n\nهل ترى المشكلة؟ يتم تهيئة الحقل مرتين! أولاً بالقيمة الافتراضية (من مُهيئ الحقل)، ثم بالقيمة من المُنشئ. إذا كان لديك 10 حقول، سيكون هناك 20 عملية إسناد بدلاً من 10. في المحركات الحديثة، قد لا يكون هذا ملحوظًا، ولكن في الأنظمة عالية التحميل، كل ميكروثانية لها أهميتها.
\n\nأداء مُهيئات الحقول: اختبارات وأرقام حقيقية
\n\nلنقم بتجربة ذهنية صغيرة. لنفترض أن لدينا فئة بها 5 حقول، ونقوم بإنشاء 100,000 نسخة. دعنا نقارن بين طريقتين:
\n\n- \n
- الطريقة أ — يتم تهيئة جميع الحقول عبر مُهيئات الحقول، ثم يتم إعادة كتابتها في المُنشئ. \n
- الطريقة ب — يتم تهيئة الحقول فقط في المُنشئ. \n
النتائج (بناءً على اختبارات أداء (benchmarks) من مشاريع حقيقية):
\n- \n
- الطريقة أ: أبطأ بنسبة ~15-20% عند إنشاء الكائنات. \n
- الطريقة ب: أسرع، لكن الكود أقل قابلية للقراءة. \n
لكن هناك فارق بسيط: إذا كنت تستخدم TypeScript مع هدف ES5 أو إصدار أقدم، فإن مُهيئات الحقول قد تُنشئ كودًا أكثر، بما في ذلك التحقق من undefined. في الإصدار الحديث