الميزات الإضافية للفئات في JavaScript
في هذه المقالة، سنشرح الميزات الإضافية للفئات في JavaScript۔
YouTube Video
الميزات الإضافية للفئات في JavaScript
الخصائص الخاصة في JavaScript
في JavaScript، الخصائص الخاصة هي الخصائص التي يمكن الوصول إليها فقط داخل الكائن أو الفئة.۔ يتيح هذا تصميم كود أكثر أمانًا وقوة من خلال توفير التغليف، بحيث لا يكون التعديل المباشر أو الرجوع من الكود الخارجي ممكنًا.۔
في ECMAScript 2020 (ES11)، الذي تم تقديمه في عام 2020، تم إدخال استخدام الرمز #
لتعريف الحقول الخاصة داخل الأصناف (الكلاسات). وهذا يوفر طريقة أوضح من الاتفاقية التقليدية في جافاسكريبت لجعل المتغيرات خاصة (مثل تسمية المتغيرات التي تبدأ بشرطة سفلية).۔ يوفر هذا طريقة أوضح، مما يحل محل الاتفاقيات التقليدية للخصائص الخاصة في JavaScript (مثل أسماء المتغيرات التي تبدأ بشرطة سفلية).۔
كيفية استخدام الخصائص الخاصة
تعريف الخصائص الخاصة في الفئات
يتم تعريف الحقول الخاصة باستخدام اسم يبدأ بـ #
.۔ لا يمكن الوصول إلى هذا الحقل مباشرة من مثيلات الفئة أو الفئات الفرعية منها.۔
1class Person {
2 // Define private property
3 #name;
4
5 constructor(name) {
6 this.#name = name;
7 }
8
9 // Method to access the private property
10 getName() {
11 return this.#name;
12 }
13
14 // Method to change the private property
15 setName(newName) {
16 this.#name = newName;
17 }
18}
19
20const john = new Person("John");
21console.log(john.getName()); // John
في الكود أعلاه، #name
هو خاصية خاصة لا يمكن الوصول إليها مباشرة من خارج فئة Person
.۔ يمكنك الوصول أو تغيير الاسم فقط من خلال طرق getName
وsetName
.۔
1// Cannot access private property directly
2console.log(john.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class
تعريف الأساليب الخاصة
مثل الخصائص الخاصة، يتم تعريف الأساليب الخاصة أيضًا باستخدام اسم يبدأ بـ #
.۔ لا يمكن استدعاء الأساليب الخاصة إلا من داخل الفئة.۔
1class Counter {
2 #count = 0;
3
4 increment() {
5 this.#count++;
6 this.#logCount(); // Calling private method
7 }
8
9 // Private method
10 #logCount() {
11 console.log(`Current count: ${this.#count}`);
12 }
13}
14
15const counter = new Counter();
16counter.increment(); // Current count: 1
هنا، تم تعريف #logCount
كأسلوب خاص ولا يمكن الوصول إليه من خارج الفئة.۔ يُستخدم هذا الأسلوب فقط داخل الفئة.۔
1// Cannot access private method directly
2counter.#logCount(); // SyntaxError: Private field '#logCount' must be declared in an enclosing class
مزايا واعتبارات الخصائص الخاصة
ميزة
- التغليف: يخفي الحالة الداخلية عن الخارج ويحافظ على تناسق البيانات۔
- الأمان: يمنع الخصائص من التعديل غير المقصود بواسطة الكود الخارجي.۔
- تحسين القابلية للصيانة: يخفي تنفيذ الكائنات أو الفئات ويوضح الواجهة التي تُعرض للخارج۔
ملاحظات
- نظرًا لأن الحقول الخاصة تكون مخفية تمامًا عن خارج الفئة، قد يصبح الاختبار وتصحيح الأخطاء أمرًا صعبًا.۔ لذا، من المهم توفير واجهة برمجة تطبيقات (API) يمكن اختبارها بشكل كامل في مرحلة التصميم.۔
- تتصرف الحقول الخاصة بشكل مختلف عن الأجزاء الأخرى من JavaScript ذات الخصائص المستندة إلى النماذج، لأنها فريدة لكل كائن (instance).۔
التنفيذ التقليدي للخصائص الخاصة المزيفة
قبل تقديم الحقول الخاصة باستخدام #
، لم يكن لدى JavaScript صيغة رسمية للخصائص الخاصة.۔ لذلك، في الماضي، تم تنفيذ الخصائص الخاصة المزيفة بالطرق التالية:۔
اتفاقية استخدام الشرطة السفلية (Underscores)
أشار المطورون تقليديًا إلى الخصائص 'الخاصة' بإضافة شرطة سفلية إلى بداية أسماء المتغيرات.۔
1class Car {
2 constructor(brand) {
3 this._brand = brand; // Using an underscore to indicate private
4 }
5
6 getBrand() {
7 return this._brand;
8 }
9}
10
11const car = new Car("Toyota");
12console.log(car.getBrand()); // Toyota
13console.log(car._brand); // Toyota (Accessible from outside)
هذه الطريقة مجرد 'اتفاقية'، وفي الواقع يمكن الوصول إلى الخصائص من الخارج.۔
تنفيذ الخصائص الخاصة باستخدام الإغلاق (Closures)
من الممكن أيضًا تحقيق الخصائص الخاصة باستخدام الإغلاق (Closures) مع نطاق الوظيفة.۔
1function createPerson(name) {
2 let _name = name; // Private variable within function scope
3
4 return {
5 getName: function() {
6 return _name;
7 },
8 setName: function(newName) {
9 _name = newName;
10 }
11 };
12}
13
14const person = createPerson("Alice");
15console.log(person.getName()); // Alice
16person.setName("Bob");
17console.log(person.getName()); // Bob
18
19// Cannot access directly from outside
20console.log(person._name); // undefined
بهذه الطريقة، يتم تضمين المتغير _name
داخل نطاق الوظيفة ولا يمكن الوصول إليه مباشرةً من الخارج.۔
الملخص
الخصائص الخاصة في JavaScript فعّالة جدًا في توفير التغليف (Encapsulation) في تصميم الفصول (Classes) والكائنات (Objects)، مما يساعد على حماية البيانات بشكل آمن.۔ توفر صيغة #
للحقول الخاصة التي تم تقديمها في ES2020 طريقة أوضح وأكثر أمانًا لإدارة الخصوصية مقارنة بالاتفاقيات التقليدية والإغلاق (Closures).۔
التسلسل الاختياري (Optional Chaining) في JavaScript
تسلسل الخيارات هو بناء جملة مفيد للغاية في جافاسكريبت للوصول إلى خصائص الكائنات المتداخلة بعمق۔ يعزز من قابلية قراءة الكود وصيانته من خلال السماح بالوصول الآمن دون الحاجة إلى التحقق الفردي من وجود خصائص محددة.۔
الصيغة الأساسية للتسلسل الاختياري
يمكن استخدام تسلسل الخيارات بوضع علامة ؟
قبل النقطة أو قبل القوسين المستخدمين للوصول إلى الخصائص۔ تعيد هذه الصيغة undefined
عندما تكون الخاصية التي يتم تصفحها null
أو undefined
، مما يسمح للبرنامج بالاستمرار في المعالجة بأمان دون إلقاء خطأ.۔
مثال:
1const user = {
2 name: 'John',
3 address: {
4 street: '123 Main St',
5 city: 'New York'
6 }
7};
8
9// Without using optional chaining
10const city = user && user.address && user.address.city;
11console.log(city); // New York
12
13// Using optional chaining
14const cityWithOptionalChaining = user?.address?.city;
15console.log(cityWithOptionalChaining); // New York
في هذا المثال، نحن نصل إلى الخاصية address
وخصيصتها city
التابعة لكائن user
.۔ بدون استخدام السلسلة الاختيارية، ستحتاج إلى إجراء فحوصات متعددة للتأكد من وجود العناصر، ولكن باستخدام السلسلة الاختيارية، يمكنك الوصول بأمان إلى الخاصية ببيان واحد۔
استخدام السلسلة الاختيارية مع المصفوفات والدوال
السلسلة الاختيارية لا تقتصر فقط على خصائص الكائنات، ولكنها تنطبق أيضًا على عناصر المصفوفات واستدعاءات الدوال۔
مثال مع المصفوفات:
1const users = [{ name: 'Alice' }, { name: 'Bob' }];
2
3// Accessing the non-existent third element
4const thirdUser = users[2]?.name;
5console.log(thirdUser); // undefined
- بهذه الطريقة، يمكنك أيضًا الوصول إلى عناصر المصفوفة باستخدام التسلسل الاختياري.۔
مثال مع الدوال:
1const user = {
2 greet: function() {
3 return 'Hello!';
4 }
5};
6
7// Call the function only if greet exists
8const greeting = user.greet?.();
9console.log(greeting); // Hello!
10
11// Return undefined if greet does not exist
12const nonExistentGreeting = user.nonExistentMethod?.();
13console.log(nonExistentGreeting); // undefined
- كما هو موضح في هذا المثال، يمكن أيضًا تطبيقه على استدعاءات الدوال.۔
دمج السلسلة الاختيارية مع القيم الافتراضية
عند استخدام السلسلة الاختيارية، من الشائع استخدام عامل أو المنطقي (||
) أو عامل الدمج إذا كان فارغًا (??
) لتحديد القيم الافتراضية إذا لم تكن الخاصية موجودة۔
مثال:
1const user = {
2 name: 'John',
3 address: {
4 city: 'New York'
5 }
6};
7
8// Set a default value for a non-existent property
9const state = user?.address?.state || 'Unknown';
10console.log(state); // Unknown
11
12// Example using the nullish coalescing operator
13const zipCode = user?.address?.zipCode ?? '00000';
14console.log(zipCode); // 00000
يعامل عامل OR المنطقي القيم مثل false
و0
و''
على أنها قيم خاطئة، في حين أن عامل الدمج لـ null يستخدم القيمة الافتراضية فقط عند كون القيمة null
أو undefined
.۔
فوائد السلسلة الاختيارية
- الوصول الآمن إلى الكائنات المتداخلة: باستخدام السلسلة الاختيارية، لم تعد بحاجة إلى القيام بفحوصات وجود صريحة، مما يجعل الكود أكثر اختصارًا۔
- تجنب الأخطاء: يمكن أن يمنع أخطاء وقت التشغيل حتى إذا كانت الخاصية تساوي
null
أوundefined
۔ - تحسين قابلية القراءة والصيانة: خاصة عند التعامل مع العديد من الكائنات المتداخلة، يتم تحسين قابلية قراءة الكود إلى حد كبير۔
التحذيرات مع السلسلة الاختيارية
- الاستخدام المتكرر للسلسلة الاختيارية قد يكون علامة على أن تصميم هيكل البيانات معقد للغاية۔ يجب أن تسعى لتبسيط نموذج البيانات۔
- نظرًا لأن بعض المتصفحات القديمة ومحركات JavaScript لا تدعمها، قد تحتاج إلى استخدام polyfills أو transpilers۔
الخاتمة
السلسلة الاختيارية ميزة قوية تبسط الوصول الآمن إلى خصائص ودوال الكائنات المتداخلة في JavaScript۔ فهي فعّالة بشكل خاص عند الوصول إلى هياكل بيانات متداخلة بعمق، مما يساعد في منع الأخطاء وتحسين قابلية قراءة الكود۔
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔