Generics في JavaScript: لماذا هي ضرورية وكيفية استخدامها

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة
```html

Generics في JavaScript: لماذا هي مطلوبة وكيفية استخدامها



في عالم التطوير الحديث باستخدام JavaScript و Node.js، نجد مفهوم Generics (الأدوية، أو الأنواع العامة) بشكل متزايد. على الرغم من أن JavaScript الأصلي لا يدعم الكتابة الصارمة، إلا أن أدوات مثل TypeScript و JSDoc تسمح بإدخال آليات قوية للبرمجة العامة. في هذه المقالة، سنشرح لماذا نحتاج إلى Generics، وكيف تعمل في سياق Node.js، وكيفية استخدامها بشكل صحيح.



ما هي Generics ولماذا نحتاج إليها؟



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



المزايا الرئيسية لـ Generics:

  • أمان الأنواع — يتم اكتشاف أخطاء الأنواع في مرحلة التجميع/التحقق، وليس في وقت التشغيل.
  • إعادة استخدام الكود — دالة واحدة تعمل مع أي نوع من البيانات.
  • قابلية القراءة — يصبح الكود موثقاً ذاتياً.
  • التكامل مع بيئة التطوير — يعمل الإكمال التلقائي وتلميحات الأنواع بشكل صحيح.


في Node.js، تكون Generics مفيدة بشكل خاص عند العمل مع قواعد البيانات، وطلبات API، ومجموعات البيانات، والأدوات المساعدة.



Generics في TypeScript (الطريقة الأساسية)



TypeScript هي طبقة فوق JavaScript تضيف الكتابة الثابتة. في TypeScript، يتم تنفيذ Generics بشكل كامل. دعنا نلقي نظرة على الصيغة الأساسية.



دالة عامة بسيطة



// بدون Generics — نضطر لاستخدام anyfunction identity(arg: any): any {    return arg;}

// مع Generics — يتم الحفاظ على النوعfunction identity<T>(arg: T): T { return arg;}

// الاستخدامconst num = identity<number>(42); // نوع numberconst str = identity<string>("hello"); // نوع string


الأقواس الزاوية <T> هي إعلان لمعامل النوع. T هو اسم تقليدي، يمكن أن يكون أي شيء (غالباً ما يستخدم T، U، V).



Generics مع المصفوفات



من أكثر الحالات شيوعاً العمل مع المصفوفات:



// دالة تعيد العنصر الأول من المصفوفةfunction getFirst<T>(arr: T[]): T | undefined {    return arr[0];}

const firstNumber = getFirst([1, 2, 3]); // numberconst firstString = getFirst(["a", "b", "c"]); // string


أنواع متعددة



يمكن استخدام عدة معاملات للنوع:



function pair<T, U>(first: T, second: U): [T, U] {    return [first, second];}

const result = pair(42, "answer"); // نوع [number, string]


القيود (Constraints) في Generics



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



// دالة تعمل فقط مع الكائنات التي تحتوي على خاصية lengthfunction getLength<T extends { length: number }>(arg: T): number {    return arg.length;}

getLength("hello"); // 5 — السلسلة لها lengthgetLength([1, 2, 3]); // 3 — المصفوفة لها length// getLength(42); // خطأ! number ليس له length


هذا مفيد بشكل خاص في Node.js عند العمل مع البفرات والسلاسل والمصفوفات — كل ما له خاصية length.



Generics في الكلاسات والواجهات



تعمل Generics بشكل ممتاز ليس فقط مع الدوال، ولكن أيضاً مع الكلاسات والواجهات.



كلاس عام



مثال على مكدس بسيط في Node.js:



class Stack<T> {    private items: T[] = [];

push(item: T): void { this.items.push(item); }

pop(): T | undefined { return this.items.pop ```

المدونات

توصيات الكتب