مقدمة إلى تغيير الكائنات في جافا سكريبت

في البرمجة، يشير تغيير كائن إلى أن حالة الكائن أو بياناته قد تغيرت بعد إنشائه. بمعنى آخر، العملية التي تغير سمات الكائن في JavaScript تعرف بتغيير الكائن. تغيير الكائن يعدل قيم الكائن مباشرة، مما يجعل الأمر صعبًا، خصوصًا في التطبيقات التي قد تحاول فيها عمليات متعددة القراءة من كائن أو الكتابة إليه في نفس الوقت.

تقدم هذه المقالة مناقشة حول تغيير الكائن في JavaScript مع أمثلة شفرة ذات صلة حيثما كان ذلك ضروريًا.

أنواع البيانات في JavaScript

تشير أنواع البيانات إلى نوع البيانات التي يمكن أن يحتوي عليها متغير أو كائن. JavaScript يدعم فئتين متميزتين من أنواع البيانات: الأنواع البدائية والأنواع المعرفة من قبل المستخدم أو الأنواع المرجعية.

أنواع البيانات البدائية

في JavaScript، جميع أنواع البيانات البدائية غير قابلة للتغيير بطبيعتها، أي أنه لا يمكنك تعديلها بعد إنشائها. الأعداد، القيم البولينية، السلاسل النصية، الأعداد الكبيرة، القيم غير المعرفة، القيم الفارغة، الرموز، والكائنات هي أمثلة على الأنواع البدائية.

أنواع البيانات المعرفة من قبل المستخدم أو الأنواع المرجعية

أنواع البيانات المعرفة من قبل المستخدم أو الأنواع المرجعية هي كائنات تم إنشاؤها باستخدام الأنواع البدائية أو مزيج من الأنواع البدائية وأنواع المعرفة من قبل المستخدم. الأمثلة الشائعة على الأنواع المعرفة من قبل المستخدم أو الأنواع المرجعية هي الكائنات والمصفوفات.

كيف يتم تعيين المتغيرات وإعادة تعيينها في JavaScript

عندما تُسند متغير نوع بدائي إلى متغير بدائي، يحتوي المتغيران على قيم مماثلة، ولكنهما مخزنان في مواقع تخزين مختلفة. على سبيل المثال، نفترض أن لديك متغيرين varA و varB وتُسند قيمة متغير إلى آخر بالطريقة التالية:

JavaScript

 

عند تنفيذ القطعة السابقة من الكود، سيتم عرض الرقم 100 على وحدة التحكم. الآن، قم بتغيير قيمة أحد المتغيرين (مثلاً varB) كما يظهر هنا.

JavaScript

 

لاحظ كيف تم تغيير قيمة المتغير varB إلى 500. عند طباعة قيمة varA، ستظل القيمة 100. هذا يحدث لأن هذه المتغيرات varA و varB مخزنة في مواقع ذاكرة مختلفة. لذلك، إذا قمت بتغيير أيًا منهما، فإن القيمة الجديدة أو المُغيرة لن تنعكس على المتغيرات الأخرى.

ما هي تحويلات الكائن في جافا سكريبت؟

في جافا سكريبت، يمكن أن ينتمي نوع البيانات للكائن إلى أي من فئتين: بدائي أو غير بدائي. بينما الأنواع البدائية لا تتغير، أي أنه لا يمكنك تغييرها بعد إنشائها، يمكنك تعديل أنواع البيانات غير البدائية، أي الكائنات والمصفوفات. الكائنات تسمح دائمًا بتغيير قيمها. لذا، يمكنك تغيير حالة الحقول لنوع قابل للتغيير دون إنشاء نسخة جديدة.

تحويلات الكائن يمكن أن تخلق عدة مشاكل، مثل ما يلي:

  • يمكن أن تؤدي الكائنات المُحوَّلة في كثير من الأحيان إلى حالات منافسة بسبب مشاكل التزامن وأمان الخيوط
  • التحول يمكن أن يقدم تعقيدات في الشيفرة المصدرية بسبب قضايا التنبؤ وأمان الخيوط
  • التحول غالبًا ما يؤدي إلى وجود علل يمكن أن تكون صعبة التحديد في شيفرة مصدر التطبيق
  • التحول يجعل اختبار الشيفرة وتصحيح الأخطاء أمرًا صعبًا لأن تتبع الشيفرة التي تستفيد من التحول يصبح تحديًا

أمثلة على الشيفرة توضح تحول الكائن

يمكن أن يحدث تحول الكائن في أي من السيناريوهات التالية:

  • إضافة، تحرير، أو إزالة الخصائص
  • استخدام الأساليب التي يمكن أن تظهر تحولًا

عند تعديل خصائص كائن، سواء مباشرة أو غير مباشرة، فإنك في الأساس تقوم بتحويل الكائن. يوضح مقتطف الشيفرة التالي كيف يمكنك تحويل كائن عن طريق تغيير خاصيته.

JavaScript

 

في قطعة الشيفرة السابقة، ننشئ كائنًا يسمى الكاتب يحتوي على خاصيتين، وهما، id و name. بينما تُستخدم الخاصية id لتخزين id لسجل الكاتب، تقوم الخاصية name بتخزين اسم الكاتب. لاحظ كيف نقوم بتحويل كائن الكاتب عن طريق تغيير القيمة المتعلقة بخاصية id. بعد ذلك، نضيف خاصية جديدة، تسمى city، إلى كائن الكاتب ونعين قيمة للخاصية.

عند تشغيل قطعة الشيفرة السابقة، سيتم عرض الخصائص وقيمها لكائن الكاتب كما هو موضح أدناه:

JavaScript

 

عند تمرير كائن إلى دالة أو تعيينه إلى متغير في جافا سكريبت، فأنت تمرر بالأساس الإشارة إلى الكائن وليس نسخة منه. وهذا يعني أن أي تغيير تقوم به على الكائن الجديد الذي تم تمريره كمعلمة للدالة أو تعيينه إلى المتغير سينعكس على جميع الإشارات للكائن الفعلي.

ننظر في الشيفرة التالية التي توضح كيف يمكنك إنشاء كائن في جافا سكريبت ثم تعيينه إلى متغير.

JavaScript

 

في الشيفرة السابقة، يتم تعيين الكائن objA إلى objB، ويتم تغيير قيمة خاصية pincode للكائن objA، أي يتم تحويل الكائن objA. عند تنفيذ البرنامج، ستعرض البيانات التالية.

JavaScript

 

يرجى ملاحظة أن قيمة خاصية pincode قد تم تغييرها.

منع تحويل الكائن في جافا سكريبت

في جافا سكريبت، يمكنك منع التحويل بعدة طرق، مثل ما يلي: 

  • استخدام نسخ الكائن باستخدام طريقة Object.assign() أو عامل الانتشار (…)
  • استخدام طريقة Object.seal() لمنع إضافة أو حذف الخصائص من كائن
  • استخدام طريقة Object.freeze() لمنع إضافة، تحرير، أو حذف الخصائص من كائن

استخدام النسخ

راجع الشيفرة التالية التي توضح كيف يمكنك نسخ كائن في جافا سكريبت باستخدام عامل الانتشار.

JavaScript

 

هنا، اسم الكائن المستنسخ هو clonedObj، وهو مطابق للكائن الأصلي المسمى originalObj. لذا، إذا عرضت قيم الخاصيتين لهذين الكائنين، ستكون النتائج متطابقة.

الآن، قم بتغيير قيمة إحدى الخصائص للكائن المستنسخ المسمى clonedObj إلى القيمة المرغوبة، كما هو موضح في الكود التالي.

Plain Text

 

الآن، اكتب الكود التالي لعرض قيمة الخاصية المسماة x المتعلقة بالكائنين originalObj و clonedObj.

Plain Text

 

عند تشغيل البرنامج، ستلاحظ أن قيمة الخاصية x في الكائن الأصلي لم تتغير. سيتم عرض القيم على وحدة التحكم كما هو موضح أدناه:

Plain Text

 

استخدام طريقة Object.freeze()

تستطيع طريقة Object.freeze() جعل كائن لا يمكن تغييره عن طريق منع أي تعديل على أي من خصائصه.

JavaScript

 

عند تنفيذ الكود السابق، ستكون النتائج مماثلة لهذا:

JavaScript

 

كما يمكنك رؤية من النتائج، حتى إذا قمت بتعيين قيم للخصائص city و state، و pincode، لا يوجد تأثير. لذا، لم يتم إجراء أي تغييرات على البيانات الواردة في أي من الخصائص للكائن.

استخدام طريقة Object.seal()

يمكنك أيضًا استخدام طريقة Object.seal() لمنع تحويل الكائن في جافا سكريبت. تمكنك هذه الطريقة من تعديل قيم الخصائص الحالية، ولكن لا يمكنك تعديل أو حذف أي من خصائص الكائن. يوضح المثال الكودي التالي هذا:

JavaScript

 

في مقتطف الشيفرة السابق، سيُسمح بتعديل خصائص الكائن المسمى بالمؤلف، لكن لن يُسمح بإضافة أو حذف خصائص الكائن. عند تشغيل البرنامج، ستظهر قيم الخصائص المعدلة في النتيجة، ولكن البيانات التي تقوم بإضافة أو حذف الخصائص تُتجاهل. إليك كيف يبدو الإخراج على واجهة الطرفية:

JavaScript

 

باستخدام طريقة Object.defineProperty()

يمكنك أيضًا استغلال طريقة Object.defineProperty() في JavaScript للتحكم في قابلية تغيير خصائص كائن بشكل فردي. يوضح مقتطف الشيفرة التالي كيف يمكنك استخدام هذه الطريقة لمنع تعديل القيمة الموجودة في خاصية تم تقييدها من التغير.

JavaScript

 

عند تنفيذ قطعة الشيفرة السابقة، سترى أن الرقم 3 يتم عرضه على واجهة الطرفية.

نقاط رئيسية

  • يصنف JavaScript أنواع الكائنات إلى فئتين متميزتين: الأساسيات (قابلة للتغيير) والكائنات (غير قابلة للتغيير).
  • مصطلح تحوير الكائن يشير إلى العمليات التي تقوم بتعديل أو تغيير كائن بعد إنشائه.
  • بينما لا يمكن تغيير القيم الأساسية مثل الرقم، وما إلى ذلك، يمكنك دائمًا تغيير الكائنات بعد إنشائها.
  • نظرًا لأن السلاسل في JavaScript غير قابلة للتغيير، فلا يمكنك تعديلها بمجرد إنشائها.
  • على الرغم من أن التحوير بحد ذاته ليس بالأمر السيء، يجب إدارته بعناية لتقليل الأخطاء في تطبيقاتك.
  • يمكنك تقليل أو القضاء على التحوير في JavaScript عن طريق اتباع الممارسات الموصى بها واستغلال هياكل البيانات غير القابلة للتغيير.

Source:
https://dzone.com/articles/an-introduction-to-object-mutation-in-javascript