الميزات الإضافية للفئات في 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
22
23// Cannot access private property directly
24console.log(john.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class
في الكود أعلاه، #name
هو خاصية خاصة لا يمكن الوصول إليها مباشرة من خارج فئة Person
.۔ يمكنك الوصول أو تغيير الاسم فقط من خلال طرق getName
وsetName
.۔
تعريف الأساليب الخاصة
مثل الخصائص الخاصة، يتم تعريف الأساليب الخاصة أيضًا باستخدام اسم يبدأ بـ #
.۔ لا يمكن استدعاء الأساليب الخاصة إلا من داخل الفئة.۔
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
17
18// Cannot access private method directly
19counter.#logCount(); // SyntaxError: Private field '#logCount' must be declared in an enclosing class
هنا، تم تعريف #logCount
كأسلوب خاص ولا يمكن الوصول إليه من خارج الفئة.۔ يُستخدم هذا الأسلوب فقط داخل الفئة.۔
مزايا واعتبارات الخصائص الخاصة
ميزة
- نظرًا لأنه لا يمكن الوصول إليه مباشرةً من خارج الفئة، فإن ذلك يمنع التغييرات أو العمليات غير المقصودة.۔
- نظرًا لأن الأجزاء غير المرئية من الخارج يمكن إخفاؤها جيدًا، يمكنك إدارة الأجزاء التي تعرضها كواجهة برمجة التطبيقات (API) بوضوح.۔
ملاحظات
- نظرًا لأن الحقول الخاصة تكون مخفية تمامًا عن خارج الفئة، قد يصبح الاختبار وتصحيح الأخطاء أمرًا صعبًا.۔ لذا، من المهم توفير واجهة برمجة تطبيقات (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
التسلسل الاختياري (Optional Chaining) هو صيغة مفيدة للغاية في JavaScript للوصول إلى خصائص الكائنات المتداخلة بشكل عميق.۔ يعزز من قابلية قراءة الكود وصيانته من خلال السماح بالوصول الآمن دون الحاجة إلى التحقق الفردي من وجود خصائص محددة.۔
الصيغة الأساسية للتسلسل الاختياري
يمكن استخدام التسلسل الاختياري (Optional Chaining) بوضع ?
قبل النقطة (.
) أو صيغة الأقواس المستخدمة للوصول إلى الخصائص.۔ تعيد هذه الصيغة 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
عامل ||
يعتبر false
و 0
و ''
وما إلى ذلك كقيم خاطئة، بينما عامل ??
يستخدم القيمة الافتراضية فقط إذا كان المتغير null
أو undefined
۔
فوائد السلسلة الاختيارية
- الوصول الآمن إلى الكائنات المتداخلة: باستخدام السلسلة الاختيارية، لم تعد بحاجة إلى القيام بفحوصات وجود صريحة، مما يجعل الكود أكثر اختصارًا۔
- تجنب الأخطاء: يمكن أن يمنع أخطاء وقت التشغيل حتى إذا كانت الخاصية تساوي
null
أوundefined
۔ - تحسين قابلية القراءة والصيانة: خاصة عند التعامل مع العديد من الكائنات المتداخلة، يتم تحسين قابلية قراءة الكود إلى حد كبير۔
التحذيرات مع السلسلة الاختيارية
- الاستخدام المتكرر للسلسلة الاختيارية قد يكون علامة على أن تصميم هيكل البيانات معقد للغاية۔ يجب أن تسعى لتبسيط نموذج البيانات۔
- نظرًا لأن بعض المتصفحات القديمة ومحركات JavaScript لا تدعمها، قد تحتاج إلى استخدام polyfills أو transpilers۔
الخاتمة
السلسلة الاختيارية ميزة قوية تبسط الوصول الآمن إلى خصائص ودوال الكائنات المتداخلة في JavaScript۔ فهي فعّالة بشكل خاص عند الوصول إلى هياكل بيانات متداخلة بعمق، مما يساعد في منع الأخطاء وتحسين قابلية قراءة الكود۔
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔