التحقق من وجود مفتاح في كائن JavaScript: شرح للمبتدئين
\n\nهل سبق لك أن حاولت الحصول على قيمة من كائن JavaScript، وبدلاً من ذلك حصلت على undefined الغامض؟ موقف مألوف، أليس كذلك؟ خاصة عند العمل مع بيانات من API أو ملفات التهيئة أو الهياكل الكبيرة. اليوم سنفهم مرة وإلى الأبد كيفية التحقق بشكل صحيح من وجود مفتاح في كائن. هذا أحد أكثر الأسئلة شيوعًا على Stack Overflow - وليس بدون سبب.
تخيل أن الكائن هو خزانة ذات أدراج. تريد معرفة ما إذا كان هناك درج مكتوب عليه "مفاتيح". يمكنك ببساطة سحب المقبض (وستحصل على خطأ إذا لم يكن الدرج موجودًا)، أو يمكنك أولاً إلقاء نظرة والتأكد. في JavaScript، لدينا ثلاث طرق موثوقة للقيام بذلك. هيا بنا!
\n\nلماذا التحقق من وجود المفتاح أساسًا؟
\n\nلنفترض أنك تكتب تطبيقًا لقائمة التسوق. لديك كائن cart قد يحتوي على عناصر مع الكمية:
const cart = {\n apples: 3,\n bananas: 5\n};\n\n// نريد إضافة كمثرى، لكننا لا نعرف ما إذا كانت موجودة بالفعل\nfunction addItem(item, quantity) {\n if (cart[item] !== undefined) {\n cart[item] += quantity;\n } else {\n cart[item] = quantity;\n }\n}\n\nهذا الكود سيعمل، لكن له عيوب خفية. ماذا لو كانت قيمة المفتاح هي 0 أو null؟ عندها سيعطي التحقق من undefined نتيجة خاطئة. لذلك دعونا نستعرض الطرق الاحترافية.
الطريقة 1: عامل التشغيل in - الجندي العالمي
\n\nعامل التشغيل in يتحقق مما إذا كانت الخاصية موجودة في الكائن، بما في ذلك الخصائص الموروثة. هذه هي الطريقة الأكثر موثوقية عندما تحتاج إلى معرفة ما إذا كان المفتاح موجودًا أم لا.
const user = {\n name: 'آنا',\n age: 25,\n isAdmin: false\n};\n\nconsole.log('name' in user); // true\nconsole.log('age' in user); // true\nconsole.log('salary' in user); // false\nconsole.log('toString' in user); // true (موروث من Object)\n\nالمزايا: يعمل حتى لو كانت القيمة null أو undefined أو false. يتحقق من سلسلة النماذج الأولية بأكملها.
العيوب: قد يجد خصائص موروثة لا تحتاجها. على سبيل المثال، toString أو hasOwnProperty.
في معظم الحالات، in هو الخيار المثالي. خاصة عند العمل مع كائنات القاموس العادية.
الطريقة 2: hasOwnProperty() - المفاتيح الخاصة فقط
\n\nإذا كنت بحاجة إلى التحقق فقط من الخصائص الخاصة بالكائن (غير الموروثة)، استخدم طريقة hasOwnProperty. هذه هي الطريقة القياسية لجميع الكائنات في JavaScript.
const book = {\n title: 'JavaScript للدمى',\n pages: 300\n};\n\nconsole.log(book.hasOwnProperty('title')); // true\nconsole.log(book.hasOwnProperty('pages')); // true\nconsole.log(book.hasOwnProperty('toString')); // false (ليست خاصية خاصة)\nconsole.log(book.hasOwnProperty('author')); // false\n\nلاحظ: hasOwnProperty لا تتحقق من الخصائص الموروثة. هذا يجعلها لا غنى عنها عند إنشاء كائنات باستخدام الفئات أو النماذج الأولية.
لكن هناك فارق بسيط! إذا تم إنشاء الكائن الخاص بك باستخدام Object.create(null)، فلن يكون لديه طريقة hasOwnProperty. ماذا تفعل؟ استخدم الاستدعاء الآمن:
const dict = Object.create(null);\ndict.key1 = 'value1';\n\n// هذا لن يعمل:\n// console.log(dict.hasOwnProperty('key1')); // TypeError\n\n// ولكن هذا سيعمل:\nconsole.log(Object.prototype.hasOwnProperty.call(dict, 'key1')); // true\n\nبناء الجملة الحديث يسمح باستخدام Object.hasOwn() - طريقة ثابتة تمت إضافتها في ES2022. تحل هذه المشكلة بأناقة:
console.log(Object.hasOwn(dict, 'key1')); // true\n\nأوصي باستخدام Obj