تقنية

Object.hasOwn: افصل خصائص الكائن عن الخصائص الموروثة

الكائن note يملك title ويرث language من defaults.
موضع الخاصية يختلف عن إمكان العثور عليها. [1][2]

العثور على اسم خاصية لا يعني دائمًا أن الكائن يملكها؛ قد تأتي من نموذجه الأولي. [2]

استخدم Object.hasOwn لفحص الخاصية المملوكة، واستخدم in حين تريد البحث في الكائن وسلسلة نماذجه الأولية. [1][2]

الخلاصة السريعة

  • ينشئ Object.create كائنًا جديدًا يستخدم الكائن الذي تمرره نموذجًا أوليًا. [3]
  • يبحث in في الكائن وسلسلة نماذجه الأولية؛ لا يحصر الفحص في الخصائص المملوكة. [2]
  • وجود خاصية مملوكة قيمتها undefined يختلف عن غيابها؛ يعيد Object.hasOwn القيمة true للأولى. [1]
  • ينشئ Object.create(null) كائنًا بلا نموذج أولي، ويمكن فحص خصائصه باستخدام Object.hasOwn. [3][1]

أنشئ أصلًا للكائن

ينشئ Object.create كائنًا جديدًا يستخدم الكائن الذي تمرره نموذجًا أوليًا. [3]

نفّذ المقاطع بالترتيب داخل script في صفحة محلية، وافتح وحدة التحكم. نضع language في defaults، ثم نجعل defaults أصلًا للكائن note. بعد الإنشاء نضيف title إلى note نفسه؛ هذه الإضافة لا تضع الخاصية في defaults. [3]

العلاقة هنا ليست نسخًا لمحتوى الأصل إلى الكائن الجديد. اخترنا كائنًا بسيطًا لتظل المقارنة محصورة في موضع الخاصية. [3]

مرّر الشيفرة أفقيًا عند الحاجة.

const defaults = { language: "ar" };
const note = Object.create(defaults);
note.title = undefined;

حدد نطاق البحث

يبحث in في الكائن وسلسلة نماذجه الأولية؛ لا يحصر الفحص في الخصائص المملوكة. [2]

تعطي المقارنة الأولى true لأن language موجودة في الأصل. أما فحص ملكيتها داخل note فيعطي false. في المقابل، title مملوكة للكائن نفسه. اختر الفحص بحسب سؤالك: هل الاسم متاح عبر السلسلة، أم معرف مباشرة على هذا الكائن؟ [2]

مرّر الشيفرة أفقيًا عند الحاجة.

console.log("language" in note); // true
console.log(Object.hasOwn(note, "language")); // false
console.log(Object.hasOwn(note, "title")); // true

لا تستنتج الوجود من القيمة

وجود خاصية مملوكة قيمتها undefined يختلف عن غيابها؛ يعيد Object.hasOwn القيمة true للأولى. [1]

تبدو القراءتان التاليتان متطابقتين في وحدة التحكم، لكن فحص الملكية يميزهما. title أضفناها صراحة، بينما missing لم نضفها. لا تجعل ظهور undefined وحده دليلًا على غياب الخاصية. [1]

مرّر الشيفرة أفقيًا عند الحاجة.

console.log(note.title); // undefined
console.log(note.missing); // undefined
console.log(Object.hasOwn(note, "title")); // true
console.log(Object.hasOwn(note, "missing")); // false

جرّب كائنًا بلا أصل

ينشئ Object.create(null) كائنًا بلا نموذج أولي، ويمكن فحص خصائصه باستخدام Object.hasOwn. [3][1]

مرر null بدل defaults، ثم أضف title. هذا كائن جديد مستقل في التجربة؛ لا يغير note أو defaults اللذين أنشأناهما سابقًا. [3]

لا يرث هذا الكائن hasOwnProperty من Object.prototype؛ لذلك نستدعي الفحص من Object نفسه. تظل النتيجة true للخاصية التي أضفناها. [1]

أما البحث عن toString فيعطي false هنا: لم نضف الاسم، ولا توجد سلسلة أصل يجده فيها in. تقتصر العينة على كائنات عادية؛ لا تختبر مصائد Proxy أو سلوك جلب مخصص. [2]

مرّر الشيفرة أفقيًا عند الحاجة.

const bare = Object.create(null);
bare.title = "draft";
console.log(Object.hasOwn(bare, "title")); // true
console.log("toString" in bare); // false

المصادر ومتابعة القراءة

  1. MDN: ملكية الخاصية باستخدام hasOwn (يفتح في نافذة جديدة)developer.mozilla.org
  2. MDN: نطاق البحث بالمعامل in (يفتح في نافذة جديدة)developer.mozilla.org
  3. MDN: اختيار النموذج الأولي مع create (يفتح في نافذة جديدة)developer.mozilla.org

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