ال

الكائنات في JavaScript

18 تمرينًا

نبذة عن الكائنات

الشرح

إلى جانب أنواع البيانات البدائية مثل number وstring، يوجد نوع بيانات مهم آخر في JavaScript يُسمى object. الكائنات مجموعات من أزواج مفتاح-قيمة. وبذلك يمكن استخدامها بوصفها ما يُشار إليه غالبًا بالخرائط أو القواميس في لغات أخرى.

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

في ما يلي، سنركّز على الكائنات بوصفها مجموعات أو خرائط. سنغطي حالات الاستخدام الأخرى للكائنات في مفاهيم أخرى، انظر مثلًا الأصناف.

إنشاء كائن

يمكنك إنشاء كائن حرفي باستخدام الأقواس المعقوفة. يمكنك أيضًا تضمين بعض المدخلات (أزواج مفتاح-قيمة) مباشرة. لذلك، اذكر المفتاح أولًا، متبوعًا بنقطتين ثم القيمة.

const emptyObject = {};

const obj = {
  favoriteNumber: 42,
  greeting: 'Hello World',
  useGreeting: true,
  address: {
    street: 'Trincomalee Highway',
    city: 'Batticaloa',
  },
  fruits: ['melon', 'papaya'],
  addNumbers: function (a, b) {
    return a + b;
  },
};

الفاصلة التي تلي آخر مدخل اختيارية في JavaScript. يمكنك القراءة عن فوائد استخدامها هنا.

قد تتساءل لماذا لا تُوضع المفاتيح بين علامات الاقتباس رغم أنه يُفترض أن تكون سلاسل نصية. هذه صيغة مختصرة. إذا اتبع المفتاح قواعد التسمية الخاصة بـ معرّف في JavaScript، فيمكنك حذف علامات الاقتباس. أما المفاتيح التي تحتوي أسماؤها على محارف خاصة، فعليك استخدام صيغة السلسلة النصية المعتادة.

const obj = {
  '1keyStartsWithNumber': '...',
  'key/with/slashes': '...',
  'key-with-dashes': '...',
  'key with spaces': '...',
  '#&()[]{}èä樹keyWithSpecialChars': '...',
};

غالبًا ما سترغب في إضافة متغيرات موجودة عند تعريف كائن. سيؤدي ذلك غالبًا إلى أزواج مفتاح-قيمة مثل name: name. توفر JavaScript صيغة مختصرة تسمح بكتابة name فقط بدلًا من ذلك. توجد أيضًا صيغة مختصرة لتعريف دالة داخل كائن. وهناك يمكنك حذف النقطتين والكلمة المفتاحية function.

const x = 1;
const y = 2;

const obj = {
  x: x,
  y: y,
  calcSum: function (a, b) {
    return a + b;
  },
};

// Can be shortened to ...
const obj = {
  x,
  y,
  calcSum(a, b) {
    return a + b;
  },
};

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

const key = 'greeting';

const obj = {
  [key]: 'hello world',
};
console.log(obj);
// => { greeting: 'hello world' }

استرجاع قيمة

توجد طريقتان لاسترجاع قيمة مفتاح معين: الترميز النقطي وترميز الأقواس.

const obj = { greeting: 'hello world' };

obj.greeting;
// => hello world

obj['greeting'];
// => hello world

// Bracket notation also works with variables.
const key = 'greeting';
obj[key];
// => hello world

استخدام الترميز النقطي كصيغة مختصرة له القيد نفسه الذي لحذف علامات الاقتباس. فهو يعمل فقط إذا اتبع المفتاح قواعد تسمية المعرّفات.

إذا حاولت استرجاع مفتاح غير موجود في الكائن، فستحصل على undefined. انظر null و undefined لمزيد من التفاصيل حول هذا.

يمكنك تسلسل المفاتيح إذا أردت استرجاع قيمة من كائن متداخل.

const obj = {
  address: {
    street: 'Trincomalee Highway',
    city: 'Batticaloa',
  },
};

obj.address.city;
// => 'Batticaloa'

obj['address']['city'];
// => 'Batticaloa'

// Notations can also be mixed.
obj.address['city'];
// => 'Batticaloa'

إضافة قيمة أو تغييرها

يمكنك إضافة قيمة أو تغييرها باستخدام عامل الإسناد =. مرة أخرى، يتوفر الترميز النقطي وترميز الأقواس.

const obj = { greeting: 'hello world' };

obj.greeting = 'Hi there!';
obj['greeting'] = 'Welcome.';

obj.newKey1 = 'new value 1';
obj['new key 2'] = 'new value 2';

const key = 'new key 3';
obj[key] = 'new value 3';

حذف مدخل

يمكنك حذف زوج مفتاح-قيمة من كائن باستخدام الكلمة المفتاحية delete.

const obj = {
  key1: 'value1',
  key2: 'value2',
};

delete obj.key1;
delete obj['key2'];

لاحظ أنه على الرغم من أن الوصول إلى مفتاح غير موجود يُرجع undefined، فإن ضبط مفتاح على undefined لا يحذف المدخل. استخدم delete دائمًا بدلًا من ذلك.

التحقق من وجود مفتاح

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

const obj = { greeting: 'hello world' };

obj.hasOwnProperty('greeting');
// => true

obj.hasOwnProperty('age');
// => false

تُرجع hasOwnProperty القيمة false للمفاتيح الموروثة. وعادةً ما يكون هذا هو السلوك المطلوب. إذا أردت تضمين المفاتيح الموروثة في فحص الوجود، فيمكنك استخدام عامل in بدلًا من ذلك.

المرور عبر كائن

توجد حلقة خاصة for...in للمرور على جميع مفاتيح الكائن.

const obj = {
  name: 'Ali',
  age: 65,
};

for (let key in obj) {
  console.log(key, obj[key]);
}
// name Ali
// age 65

قد يبدو أن حلقة for...in تزور المفاتيح دائمًا بالترتيب الذي تظهر به أو أُضيفت به إلى الكائن (ترتيب الإدراج). ومع ذلك، لا ينبغي أن تعتمد على ذلك لأن هناك حالات خاصة يختلف فيها الترتيب عن ترتيب الإدراج. اكتب الكود دائمًا كما لو كان الترتيب عشوائيًا. إذا احتجت إلى ترتيب موثوق، فاستخدم Map أو [مصفوفة][concept-arrays] متداخلة بدلًا من كائن.

تنطوي حلقة for…in على خطأ شائع إذا كان للكائن مفاتيح موروثة. فستتم زيارتها أيضًا بواسطة حلقة for...in. ترغب عادةً في تجنب ذلك، لذا عليك تخطيها كما هو موضح أدناه.

for (let key in obj) {
  if (!obj.hasOwnProperty(key)) {
    continue;
  }
  // ...
}

تمتلك JavaScript أيضًا حلقة for...of، على سبيل المثال للمرور على المصفوفات. من المهم ملاحظة أن for...in وfor...of ليسا قابلين للتبادل، انظر توثيق MDN لمزيد من التفاصيل حول هذا.

المفاتيح والقيم والمدخلات

يوفر الكائن المدمج Object طرقًا مساعدة لاسترجاع جميع المفاتيح أو القيم أو المدخلات لكائن معين على شكل مصفوفات.

const obj = {
  name: 'Ali',
  age: 65,
};

Object.keys(obj);
// => [ 'name', 'age' ]

Object.values(obj);
// => [ 'Ali', 65 ]

Object.entries(obj);
// => [ [ 'name', 'Ali' ], [ 'age', 65 ] ]

كائن فارغ حقًا

ربما لاحظت أن الكائن الفارغ في JavaScript ليس فارغًا تمامًا. على سبيل المثال، يحتوي على طريقة hasOwnProperty وطرق أخرى مثل toString. عادةً لا يسبب ذلك أي مشكلات، لكن إذا احتجت يومًا إلى إنشاء كائن فارغ حقًا فاستخدم كائن null يمكن إنشاؤه عبر Object.create(null).

تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة

تعلّم الكائنات