الجزء السابع عشر – ما هي البرمجة الكائنية (OOP)? – سلسلة FSWD – JS

🟡 ما هي البرمجة الكائنية (OOP)?
البرمجة الكائنية (OOP) هي نمط من أنماط البرمجة بيقوم على فكرة الكائنات (objects) التي تحتوي على بيانات (تسمى الخصائص أو attributes) ودوال (تسمى الطرق أو methods) التي تعمل على هذه البيانات.
مفاهيم أساسية في OOP:
-
Classes: القوالب أو النماذج التي تُستخدم لإنشاء الكائنات.
-
Objects: الكائنات التي تُنشأ باستخدام الـ classes.
-
Inheritance: الوراثة، تعني أن كائنًا يمكنه أن يرث الخصائص والطرق من كائن آخر.
-
Encapsulation: التغليف، حيث يتم إخفاء البيانات داخل الكائنات وعدم السماح بالوصول المباشر إليها.
-
Polymorphism: تعددية الأشكال، حيث يمكن للكائنات أن تتصرف بطرق مختلفة بناءً على السياق.
🟡 1. class
و constructor
في JavaScript
class
:
في JavaScript، class
هي طريقة لتعريف قالب أو نموذج لإنشاء كائنات. الكلاسات تقوم بتجميع البيانات والوظائف المتعلقة بها معًا.
constructor
:
الـ constructor هو دالة خاصة تُنفذ عند إنشاء كائن جديد من class. يمكننا من خلالها تهيئة الكائن بالقيم الأولية.
✅ مثال على استخدام class
و constructor
// تعريف class جديدة باسم Person
class Person {
// دالة constructor لتهيئة الكائن
constructor(name, age) {
this.name = name; // الخاصية name
this.age = age; // الخاصية age
}
// دالة method لعرض معلومات الشخص
introduce() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
// إنشاء كائن من الـ class
const person1 = new Person('Ahmed', 25);
// استخدام method من الكائن
person1.introduce(); // "Hello, my name is Ahmed and I am 25 years old."
الشرح:
-
class Person
: هنا قمنا بتعريف class باسم Person. -
constructor(name, age)
: الدالة الخاصة بالتهيئة. -
this.name
وthis.age
: تعيين قيم الخصائص التي تم تمريرها في الـ constructor. -
introduce()
: دالة method تعرض معلومات الشخص.
🟡 2. Inheritance (الوراثة)
Inheritance أو الوراثة هي ميزة في OOP تسمح لكائن أن يرث الخصائص والطرق من كائن آخر. في JavaScript، يمكننا استخدام extends
لإنشاء class جديدة ترث من class موجودة.
✅ مثال على استخدام الوراثة (Inheritance):
// تعريف class أساسية باسم Animal
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
// تعريف class أخرى ترث من Animal باسم Dog
class Dog extends Animal {
constructor(name, breed) {
super(name); // استدعاء constructor من class الأب (Animal)
this.breed = breed;
}
speak() {
console.log(`${this.name} barks.`); // Overriding method
}
fetch() {
console.log(`${this.name} is fetching a ball.`);
}
}
// إنشاء كائن من class Dog
const dog1 = new Dog('Rex', 'German Shepherd');
// استخدام method من class الأب (Animal)
dog1.speak(); // "Rex barks."
dog1.fetch(); // "Rex is fetching a ball."
الشرح:
-
class Animal
: قمنا بتعريف class أساسية باسم Animal تحتوي على خاصيةname
وطريقةspeak
. -
class Dog extends Animal
: قمنا بإنشاء class Dog التي ترث من Animal. -
super(name)
: يتم استخدامsuper
لاستدعاء الـ constructor من class الأب (Animal). -
speak()
: قمنا بإعادة تعريف (Override) الـ method في class Dog بحيث يقوم الكلب بالعواء بدلاً من إصدار صوت عام.
🟡 3. Encapsulation (التغليف)
Encapsulation أو التغليف هو مفهوم في OOP حيث نقوم بإخفاء التفاصيل الداخلية للكائن (مثل الخصائص) ونتحكم في الوصول إليها عبر الطرق.
✅ كيفية تطبيق التغليف:
-
private: جعل الخصائص أو الطرق غير قابلة للوصول مباشرة من خارج الكائن.
-
public: جعل الخصائص أو الطرق قابلة للوصول من أي مكان.
في JavaScript، لم يكن هناك دعم مباشر للخصائص private حتى إصدار ES2022، حيث يمكننا الآن استخدام # لجعل الخصائص خاصة.
✅ مثال على التغليف باستخدام الـ private properties
class Car {
// الخاصية الخاصة لا يمكن الوصول إليها مباشرة من خارج الكلاس
#make;
#model;
constructor(make, model) {
this.#make = make;
this.#model = model;
}
// دالة لعرض تفاصيل السيارة
getDetails() {
return `${this.#make} ${this.#model}`;
}
// دالة لتغيير الموديل
setModel(newModel) {
this.#model = newModel;
}
}
const car1 = new Car('Toyota', 'Corolla');
// محاولة للوصول إلى الخصائص الخاصة
console.log(car1.getDetails()); // "Toyota Corolla"
// محاولة للوصول المباشر إلى #make و #model ستؤدي إلى خطأ
// console.log(car1.#make); // SyntaxError
// تغيير الموديل باستخدام دالة set
car1.setModel('Camry');
console.log(car1.getDetails()); // "Toyota Camry"
الشرح:
-
#make
و#model
: هذه الخصائص هي private ولا يمكن الوصول إليها مباشرة من خارج الكلاس. -
getDetails()
وsetModel()
: هي طرق عامة public للوصول والتفاعل مع الخصائص الخاصة.
🟡 ملخص النقاط:
-
class هي قالب أو نموذج لإنشاء كائنات (objects).
-
constructor هو دالة تُنفذ عند إنشاء كائن جديد، وتستخدم لتهيئة الكائن.
-
Inheritance (الوراثة): يسمح للكائنات بأن ترث الخصائص والطرق من كائنات أخرى باستخدام
extends
. -
Encapsulation (التغليف): يقوم بإخفاء التفاصيل الداخلية للكائن ويفرض الوصول إلى الخصائص عبر public methods.
-
في ES2022، تم إضافة دعم للخصائص private باستخدام
#
.
🟡 ما هي Regex (التعبيرات النمطية)؟
التعبيرات النمطية (Regular Expressions أو Regex) هي عبارة عن أنماط (Patterns) بيتم استخدامها للبحث أو مطابقة نصوص (Strings) بطريقة مرنة. تساعد التعبيرات النمطية في:
-
البحث عن نصوص معينة داخل نصوص أكبر.
-
التحقق من شكل النص (مثل: البريد الإلكتروني أو الأرقام).
-
استبدال النصوص.
-
تقسيم النصوص.
الـ Regex بتستخدم مجموعة من الرموز الخاصة التي بتمثل قواعد للبحث داخل النصوص. مثلاً، نقدر نستخدمها للبحث عن كل الأرقام في نص معين أو نصوص تبدأ بحرف معين.
🟡 الأساسيات في Regex
1. الرموز الخاصة (Special Characters)
-
.
: يعني أي حرف (باستثناء السطر الجديد). -
^
: يعني بداية السلسلة. -
$
: يعني نهاية السلسلة. -
*
: يعني 0 أو أكثر من العنصر الذي قبله. -
+
: يعني 1 أو أكثر من العنصر الذي قبله. -
?
: يعني 0 أو 1 من العنصر الذي قبله. -
[]
: تستخدم للتعبير عن مجموعة من الحروف (مثال:[abc]
تعني حرف “a” أو “b” أو “c”). -
{n,m}
: يعني تكرار العنصر بين n و m مرات. -
|
: يعني أو (مثل شرطين). -
()
: لتجميع العناصر معاً (مثل المجموعات).
2. الأنماط الأساسية (Basic Patterns)
-
\d
: أي رقم (0-9). -
\D
: أي حرف غير رقمي. -
\w
: أي حرف كلمة (حروف، أرقام، و_
). -
\W
: أي شيء غير حرف كلمة. -
\s
: أي مسافة بيضاء (مثل المسافة، التبويب، السطر الجديد). -
\S
: أي شيء غير مسافة بيضاء.
3. التحقق من وجود نمط (Test)
يمكنك التحقق إذا كان النص يتطابق مع النمط باستخدام الدالة test()
:
const pattern = /abc/; // نمط يبحث عن "abc"
console.log(pattern.test("abcdef")); // true
console.log(pattern.test("abcfgh")); // false
🟡 الاستخدامات العملية للتعبيرات النمطية
1. البحث عن نص داخل نص
لنبحث عن وجود رقم داخل نص
const regex = /\d/; // بحث عن أي رقم
const text = "My phone number is 12345.";
console.log(regex.test(text)); // true (لأن فيه أرقام)
2. التحقق من التنسيق (Validating)
✅ التحقق من البريد الإلكتروني (Email Validation)
يمكننا استخدام Regex للتحقق إذا كان البريد الإلكتروني صالحًا أم لا:
const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
const email = "example@example.com";
const invalidEmail = "example@com";
console.log(emailPattern.test(email)); // true
console.log(emailPattern.test(invalidEmail)); // false
-
^[a-zA-Z0-9._-]+
: بداية السلسلة ويجب أن تحتوي على أحرف أو أرقام أو نقطتين أو شرطات. -
@[a-zA-Z0-9.-]+
: بعد الـ@
يجب أن تحتوي على أحرف أو أرقام أو نقطة أو شرطة. -
\.[a-zA-Z]{2,4}$
: بعد الـ@
يوجد نقطة تليها 2 إلى 4 أحرف في النهاية.
3. استبدال نصوص باستخدام Regex (Replace)
نقدر نستخدم Regex لاستبدال جزء من النص
const text = "I have a dog. My dog is cute.";
const regex = /dog/g; // g تعني البحث في كل النصوص التي تحتوي على "dog"
const newText = text.replace(regex, "cat");
console.log(newText); // "I have a cat. My cat is cute."
في المثال ده، قمنا باستخدام replace()
لاستبدال كلمة “dog” بكلمة “cat” في النص بالكامل باستخدام التعبير النمطي /dog/g
.
4. تقسيم النصوص (Splitting Text)
نقدر نستخدم التعبيرات النمطية لتقسيم النصوص إلى أجزاء باستخدام split()
:
const text = "apple,banana,orange,grape";
const regex = /,/; // نقسم النص عند كل فاصلة
const fruits = text.split(regex);
console.log(fruits); // ["apple", "banana", "orange", "grape"]
في المثال ده، استخدمنا split()
مع التعبير النمطي /,/
لتقسيم النص إلى مصفوفة بناءً على الفواصل.
5. استخدام المجموعات (Capturing Groups)
ممكن نستخدم الأقواس ()` لجمع أجزاء من النص:
const text = "My name is Ahmed and I am 25 years old.";
const regex = /My name is (\w+) and I am (\d+) years old/;
const match = text.match(regex);
console.log(match[0]); // "My name is Ahmed and I am 25 years old"
console.log(match[1]); // "Ahmed" (الاسم)
console.log(match[2]); // "25" (العمر)
في المثال ده:
-
استخدمنا ()` لإنشاء مجموعات داخل التعبير النمطي.
-
match[1]
يحتوي على الاسم. -
match[2]
يحتوي على العمر.
6. التحقق من رقم الهاتف (Phone Number Validation)
نقدر نستخدم Regex للتحقق من صحة رقم الهاتف
const phonePattern = /^\+?[1-9]\d{1,14}$/;
const validPhone = "+12345678901234";
const invalidPhone = "123456";
console.log(phonePattern.test(validPhone)); // true
console.log(phonePattern.test(invalidPhone)); // false
الشرح:
-
^\+?
: يبدأ برمز زائد+
بشكل اختياري. -
[1-9]
: أول رقم يجب أن يكون بين 1 و 9. -
\d{1,14}
: يجب أن يكون هناك بين 1 و 14 رقمًا بعد الرقم الأول.
🟡 ملخص النقاط:
-
Regex هي أداة قوية للبحث، الاستبدال، والتحقق من النصوص.
-
المجموعات (Groups) يمكن استخدامها لاستخراج أجزاء معينة من النص.
-
يمكن استخدام Regex للتحقق من البيانات مثل البريد الإلكتروني، رقم الهاتف، والمزيد.
-
test()
تستخدم للتحقق من تطابق النص مع الـ Regex. -
replace()
وsplit()
يمكن استخدامها مع Regex لأغراض الاستبدال والتقسيم.
💰 هل تبحث عن طريقة سهلة للربح من الإنترنت؟
ابدأ الآن واكسب أموالًا حقيقية من خلال خطوات بسيطة! 🌟
اضغط وابدأ الربح