الجيتّرات والستّرات في TypeScript: تحليل كامل مع أمثلة

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

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

ابدأ الدورة

Get و Set في TypeScript: سحر الأكسيسورات بدون ألم

\n\n

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

\n\n

إذا كنت قد صادفت هذا الموضوع على Stack Overflow، فأنت تعلم أن سؤال "get and set in TypeScript" يجمع آلاف المشاهدات. يختلط الأمر على الناس متى يستخدمون الأكسيسورات ومتى يستخدمون الطرق العادية. في هذه المقالة، سنرتب كل شيء: من الأساسيات إلى التفاصيل الدقيقة.

\n\n

هل أنت مستعد؟ لننطلق!

\n\n

ما هما get و set في TypeScript؟

\n\n

الجيتّر هو طريقة تُستدعى عند قراءة خاصية. الستّر هو طريقة تُستدعى عند تعيين قيمة. معًا يشكلان أكسيسورات (accessors). يبدو الأمر كما لو كنت تتعامل مع حقل عادي، ولكن تحت الغطاء يوجد منطق.

\n\n

إليك مثال بسيط:

\n\n
class User {\n  private _name: string = '';\n\n  get name(): string {\n    return this._name;\n  }\n\n  set name(value: string) {\n    if (value.length > 0) {\n      this._name = value;\n    } else {\n      console.log('الاسم لا يمكن أن يكون فارغًا');\n    }\n  }\n}\n\nconst user = new User();\nuser.name = 'آنا'; // يتم استدعاء set\nconsole.log(user.name); // يتم استدعاء get → 'آنا'\nuser.name = ''; // محاولة تعيين اسم فارغ → رسالة في الكونسول
\n\n

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

\n\n

لماذا نحتاج الجيتّرات والستّرات؟ 3 أسباب رئيسية

\n\n

1. التحقق من صحة البيانات

\n

الستّر هو المكان المثالي للتحقق من القيم المدخلة. يمكنك استبعاد البيانات غير الصحيحة قبل أن تصل إلى الكائن.

\n\n
class Temperature {\n  private _celsius: number = 0;\n\n  get celsius(): number {\n    return this._celsius;\n  }\n\n  set celsius(value: number) {\n    if (value < -273.15) {\n      throw new Error('درجة حرارة أقل من الصفر المطلق غير ممكنة');\n    }\n    this._celsius = value;\n  }\n}
\n\n

2. الخصائص المحسوبة

\n

يمكن للجيتّر أن يعيد قيمة غير مخزنة، بل نتيجة حسابات بناءً على بيانات أخرى.

\n\n
class Rectangle {\n  constructor(public width: number, public height: number) {}\n\n  get area(): number {\n    return this.width * this.height;\n  }\n\n  get perimeter(): number {\n    return 2 * (this.width + this.height);\n  }\n}\n\nconst rect = new Rectangle(10, 5);\nconsole.log(rect.area); // 50 — تُحسب فورًا
\n\n

3. التغليف والتحكم في الوصول

\n

يمكنك جعل الخاصية للقراءة فقط (جيتّر فقط) أو للكتابة فقط (ستّر فقط). هذا يساعد في الالتزام بمبادئ البرمجة كائنية التوجه.

\n\n
class Config {\n  private _apiKey: string = 'secret123';\n\n  get apiKey(): string {\n    // يمكن إضافة تسجيل أو التحقق من الصلاحيات\n    return this._apiKey;\n  }\n  // لم يتم تعريف ستّر — الخاصية للقراءة فقط\n}\n\nconst config = new Config();\nconsole.log(config.apiKey); // 'secret123'\n// config.apiKey = 'newKey'; // خطأ في الترجمة!
\n\n

أسئلة شائعة حول get و set في TypeScript

\n\n

دعنا نناقش ما يسأل عنه المبتدئون (وليس فقط) غالبًا على Stack Overflow والمنتديات.

\n\n

السؤال 1: ما الفرق بين get/set والطرق العادية؟

\n

الفرق الرئيسي هو صيغة الاستدعاء. تبدو الأكسيسورات كخصائص: بدون أقواس. هذا يجعل الكود أنظف وأكثر بديهية. قارن:

\n\n
// مع الطرق\nuser.getName();\nuser.setName('بطرس');\n\n// مع الأكسيسورات\nuser.name;\nuser.name = 'بطرس';
\n\n

الفرق الثاني هو أن الأكسيسورات لا يمكن تحميلها بشكل زائد (overload). لكل أكسيسور توقيع واحد

المدونات

توصيات الكتب