المتغير والثابت في TypeScript
توضح هذه المقالة مفاهيم المتغير والثابت في TypeScript۔
YouTube Video
المتغير والثابت في TypeScript
ما هو المتغير؟
المتغير يعني أن القيمة يمكن تغييرها۔ أنواع المراجع مثل الكائنات والمصفوفات هي أمثلة نموذجية لبُنى البيانات المتغيرة۔
مثال على كائن متغير
1type Person = { name: string; age: number };
2
3// Mutable Example: Object
4let person: Person = { name: "Alice", age: 25 };
5person.age = 26;
6console.log(person); // { name: "Alice", age: 26 }
في هذا الكود، يتم تغيير الخاصية age
في كائن person
من 25
إلى 26
۔ بما أن الكائنات يتم تمريرها كمرجع، فإن المحتويات في عنوان الذاكرة المخزن في المتغير person
يتم تعديلها۔
مثال على مصفوفة متغيرة
1// Mutable Example: Array
2let numbers: number[] = [1, 2, 3];
3numbers.push(4);
4console.log(numbers); // [1, 2, 3, 4]
في هذا الكود، يتم استخدام الطريقة push
لإضافة عنصر جديد 4
إلى المصفوفة الأصلية۔ هذا يعدل المصفوفة الأصلية، مما يجعلها عملية متغيرة۔
مثال داخل وظيفة
1// Mutable Example: Function
2function append(arr: number[], value: number): void {
3 arr.push(value); // Modify the original array
4 console.log(arr);
5}
6
7let nums: number[] = [1, 2, 3];
8append(nums, 4);
9console.log(nums); // [1, 2, 3, 4]
عند تنفيذ العمليات المتغيرة داخل وظيفة، يتم تعديل المصفوفة الأصلية أيضًا۔
ما هو الثابت؟
الثابت يعني أن القيمة لا يمكن تغييرها۔ الأنواع الأولية هي من الأساس ثابتة۔
مثال على نوع أولي ثابت
1// Immutable Example: String
2let str: string = "hello";
3str[0] = "H"; // Error: Index assignment is not allowed
4console.log(str); // "hello"
محاولة تغيير الحرف الأول من السلسلة النصية str
إلى H
ستفشل لأن السلاسل النصية ثابتة۔
مثال داخل وظيفة
1// Immutable Example: Function
2function increment(num: number): number {
3 num++; // This modifies only the local copy of num
4 return num;
5}
6
7let number: number = 10;
8console.log(increment(number)); // 11
9console.log(number); // 10 (original number remains unchanged)
بما أن الأرقام ثابتة، فإن العمليات داخل الوظيفة لا تؤثر على المتغير الأصلي۔
عمليات ثابتة على المصفوفات
المصفوفات متغيرة، ولكن بإنشاء مصفوفة جديدة بدلاً من تعديل الأصلية، يمكن تنفيذ عمليات ثابتة۔
1// Create an array of numbers
2let numbers: number[] = [1, 2, 3];
3
4// Immutable Example: Creating a new array
5let newNumbers: number[] = [...numbers, 4];
6
7console.log(numbers); // [1, 2, 3] (original array is unchanged)
8console.log(newNumbers); // [1, 2, 3, 4] (new array with an added element)
هنا، يتم استخدام بناء الجملة الانتشاري (...
) لإنشاء مصفوفة جديدة newNumbers
۔ بما أن مصفوفة numbers
الأصلية تبقى بدون تغيير، فإن هذه عملية غير قابلة للتغيير۔
فوائد استخدام هياكل البيانات غير القابلة للتغيير
تحسين القدرة على التنبؤ
البيانات غير القابلة للتغيير لا تتغير، مما يجعل التعديلات غير المتوقعة أقل احتمالاً ويقلل من فرص حدوث الأخطاء۔
التوافق مع المكتبات المستندة إلى عدم القابلية للتغيير
غالبًا ما تُصمم مكتبات مثل React
و Redux
بناءً على بيانات غير قابلة للتغيير، مما يجعل إدارة الحالة أسهل عند استخدامها بشكل مناسب۔
جعل الكائنات غير قابلة للتغيير باستخدام Object.freeze
يمكن استخدام Object.freeze
لمنع التعديلات على الكائن۔
1// Create a frozen object (properties cannot be modified)
2const person = Object.freeze({ name: "Alice", age: 25 });
3
4// Attempt to modify a property (ignored in non-strict mode, error in strict mode)
5person.age = 26;
6
7console.log(person); // { name: "Alice", age: 25 }
ومع ذلك، يقوم Object.freeze
بإجراء تجميد سطحي فقط، مما يعني أن خصائص الكائنات المتداخلة تظل قابلة للتغيير۔
1// Create a frozen object with a nested object
2const user: Readonly<{ profile: { name: string } }> = Object.freeze({
3 profile: { name: "Bob" }
4});
5
6// Attempt to modify a nested property (this works because Object.freeze() is shallow)
7user.profile.name = "Charlie"; // No TypeScript error, but still mutable
8
9console.log(user.profile.name); // "Charlie" (nested object is still mutable)
لإنشاء كائن غير قابل للتغيير تمامًا، يلزم تجميد عميق۔
1// Function to deeply freeze an object, making all nested objects immutable
2function deepFreeze<T>(obj: T): Readonly<T> {
3 Object.freeze(obj);
4 Object.getOwnPropertyNames(obj).forEach(prop => {
5 const value = (obj as any)[prop];
6 if (typeof value === "object" && value !== null) {
7 deepFreeze(value);
8 }
9 });
10 return obj;
11}
12
13// Create a deeply frozen object
14const user = deepFreeze({
15 profile: { name: "Bob" }
16});
17
18// Attempt to modify a nested property
19// (this will now throw an error in strict mode)
20user.profile.name = "Charlie"; // No TypeScript error, but modification is not allowed at runtime
21
22console.log(user.profile.name); // "Bob" (unchanged due to deep freeze)
الملخص
- البيانات القابلة للتغيير يمكن تعديلها، وتشمل الكائنات والمصفوفات۔
- البيانات غير القابلة للتغيير لا يمكن تعديلها، وتشمل الأنواع الأولية مثل النصوص والأرقام۔
- باستخدام بناء الجملة الانتشاري أو طرق مثل
map
، يمكن تنفيذ عمليات على البيانات غير القابلة للتغيير۔ - يمكن استخدام
Object.freeze
وdeepFreeze
لمنع التعديلات على الكائنات۔ - استخدام البيانات غير القابلة للتغيير يساعد في كتابة كود أكثر قابلية للتنبؤ وأقل عرضة للأخطاء۔
اعتماد تصميم غير قابل للتغيير يحسن سلامة الكود وقابليته للقراءة، لذا استفد منه بالكامل!
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔