ما هو التأمل والاستبطان في JavaScript ولماذا تحتاجهما؟
\n\nتخيل أنك مبرمج محقق. لديك كائن، لكنك لا تعرف ما بداخله. ما هي خصائصه؟ ما هي طبيعته بشكل عام - هل هو مصفوفة، دالة، أم مجرد مجموعة بيانات؟ في الحياة العادية، ننظر ببساطة إلى الكود، لكن في عالم JavaScript الديناميكي، يجب أن يكون برنامجك قادرًا على فعل ذلك بنفسه. هذا هو التأمل والاستبطان.
\n\nتبدو هذه المصطلحات وكأنها فلسفة، لكنها في الواقع أدوات قوية. الاستبطان هو عندما ينظر الكود إلى نفسه: يتحقق من نوع المتغير، يعرف اسم الدالة، أو يسرد خصائص الكائن. التأمل يذهب أبعد من ذلك - فهو قدرة الكود على تغيير نفسه أثناء التنفيذ: إضافة طرق جديدة، تغيير النماذج الأولية، أو حتى إنشاء كائنات وكيلة.
\n\nقد يبدو للوهلة الأولى أن هذا ضروري فقط لمؤلفي الأطر المعقدة. لكن في الواقع، أنت تستخدم الاستبطان كل يوم، حتى دون أن تلاحظ ذلك. عندما تكتب typeof x === 'string' - فأنت بالفعل تمارس الاستبطان. وعندما تستخدم Object.assign لنسخ الخصائص - فأنت تطبق التأمل.
في هذه المقالة، سنشرح جميع الطرق والتقنيات الرئيسية. ستتعلم كيف "تنظر داخل" أي كائن، وكيف تعمل بأمان مع بيانات غير معروفة، وكيف تكتب كودًا أكثر مرونة وتكيفًا. هيا بنا!
\n\nأساسيات الاستبطان: ننظر إلى ما لدينا في أيدينا
\n\nيبدأ الاستبطان بسؤال بسيط: "ما هذا؟". في JavaScript، هناك العديد من العوامل والطرق المدمجة التي تساعد في الإجابة على هذا السؤال.
\n\nعامل typeof: فحص سريع للنوع
\n\nهذا هو مساعدك الأول. typeof يُرجع سلسلة نصية تشير إلى نوع المعامل. إنه بسيط، لكن لديه بعض المزالق.
console.log(typeof 42); // "number"\nconsole.log(typeof 'hello'); // "string"\nconsole.log(typeof true); // "boolean"\nconsole.log(typeof undefined); // "undefined"\nconsole.log(typeof null); // "object" — ها هو الخطأ الشهير!\nconsole.log(typeof []); // "object" — وهذا ليس خطأ، بل ميزة\nconsole.log(typeof function(){}); // "function"\n\nلاحظ: typeof null يُرجع "object". هذا خطأ تاريخي في JavaScript لن يتم إصلاحه. typeof [] يُرجع أيضًا "object"، وهو منطقي لأن المصفوفة هي نوع فرعي من الكائن. لكن كيف نميز المصفوفة عن الكائن العادي؟ لهذا توجد أدوات أخرى.
نصيحة مفيدة: typeof مثالي للتحقق مما إذا كان المتغير مُعرّفًا، دون خطر إلقاء استثناء ReferenceError.
if (typeof someGlobalVar !== 'undefined') {\n // نستخدم someGlobalVar بأمان\n}\n\ninstanceof: التحقق من سلسلة النماذج الأولية
\n\nإذا كان typeof يجيب على سؤال "ما هو النوع البدائي؟"، فإن instanceof يجيب على "هل هو كائن من فئة معينة؟". يتحقق مما إذا كان النموذج الأولي للمُنشئ موجودًا في سلسلة النماذج الأولية للكائن.
const arr = [1, 2, 3];\nconsole.log(arr instanceof Array); // true\nconsole.log(arr instanceof Object); // true — لأن Array يرث من Object\n\nconst date = new Date();\nconsole.log(date instanceof Date); // true\nconsole.log(date instanceof Object); // true\n\n// لكنه لا يعمل مع البدائيات\nconsole.log('hello' instanceof String); // false — البدائي ليس كائنًا\n\nملاحظة مهمة: قد يفشل instanceof عند العمل مع iframe أو سياقات تنفيذ مختلفة (مثل Node.js). في كل سياق يوجد كائن عام خاص به، وقد يُرجع [] instanceof window.Array القيمة false إذا تم إنشاء المصفوفة في إطار آخر. لمثل هذه الحالات، من الأفضل استخدام Array.isArray().