المتغير موجود، لكنه كأنه غير موجود؟ نفهم عمليات التحقق في JavaScript
\n\nهل سبق لك أن كتبت سكريبت، وشغلته، وفجأة — بام! — تتحول وحدة تحكم المتصفح إلى اللون الأحمر مع صيحة Uncaught ReferenceError: myVar is not defined؟ مألوف. أو العكس: المتغير معلن، لكنك لست متأكدًا مما إذا كانت له قيمة. في JavaScript، هذان المفهومان («موجود» و«مهيأ») غالبًا ما يخلط بينهما حتى المطورون ذوو الخبرة.
في هذا الدليل، سنفصل مرة واحدة وإلى الأبد كيفية التحقق بشكل صحيح من وجود متغير في JavaScript، وما الفرق بين «معرف» و«مهيأ»، وكيفية تجنب 90% من الأخطاء المتعلقة بـ undefined و ReferenceError. هيا بنا!
باختصار عن الشيء الرئيسي: ماذا يعني «المتغير موجود»؟
\n\nفي JavaScript، للمتغير ثلاث حالات:
\n\n- \n
- غير معلن (undeclared) — المتغير غير موجود في الذاكرة على الإطلاق. محاولة الوصول إليه ستؤدي إلى
ReferenceError. \n - معلن لكن غير مهيأ (declared, but undefined) — كتبنا
let x;أوvar y;، لكننا لم نعطه قيمة. المتغير موجود، ونوعه هوundefined. \n - معلن ومهيأ (declared and initialized) — للمتغير قيمة محددة (رقم، نص، كائن، إلخ). \n
معظم الأسئلة على Stack Overflow (وهناك الآلاف منها) تتلخص في سؤال واحد: «كيف أعرف أن المتغير لن يسبب خطأ عند الوصول إليه؟» الإجابة — استخدم typeof. لكن هناك تفاصيل دقيقة. دعنا نفهمها.
الطريقة رقم 1. عامل typeof — صديقك الرئيسي
\n\nالطريقة الأكثر موثوقية وأمانًا للتحقق مما إذا كان المتغير معرفًا في JavaScript هي عامل typeof. ميزته الرئيسية: أنه لا يرمي خطأ أبدًا، حتى لو كان المتغير غير معلن.
مثال لمتغير غير معلن
\n\n// المتغير myVar غير معلن\nif (typeof myVar !== 'undefined') {\n console.log('المتغير موجود!');\n} else {\n console.log('المتغير غير موجود أو قيمته undefined');\n}\n// الإخراج: "المتغير غير موجود أو قيمته undefined"\n\nلاحظ: typeof يُرجع السلسلة النصية 'undefined' لكل من المتغير غير المعلن والمتغير المعلن لكن غير المهيأ (let x;). هذا جيد وسيء في نفس الوقت. جيد — لأننا لا نلتقط خطأ. سيء — لأننا لا نميز بين هاتين الحالتين.
مثال لمتغير معلن لكن فارغ
\n\nlet myVar; // معلن لكن غير مهيأ\nconsole.log(typeof myVar); // "undefined" — أيضًا undefined!\n\nif (typeof myVar !== 'undefined') {\n console.log('المتغير موجود وله قيمة');\n} else {\n console.log('المتغير undefined (إما غير معلن أو غير مهيأ)');\n}\n\nالخلاصة: typeof هو الحل المثالي إذا كنت تحتاج فقط إلى تجنب ReferenceError. أما إذا كنت بحاجة إلى التمييز بين «غير معلن» و«فارغ» — تابع القراءة.
الطريقة رقم 2. التحقق عبر window (السياق العام)
\n\nإذا كنت تعمل في المتصفح وكان المتغير معلنًا بشكل عام (عبر var أو ضمنيًا)، فإنه يصبح خاصية من خصائص الكائن window. هذا يفتح إمكانيات إضافية للتحقق من وجود المتغير.
استخدام عامل in
\n\n// متغير عام\nvar globalVar = 42;\n\nconsole.log('globalVar' in window); // true\nconsole.log('nonExistentVar' in window); // false\n\nتعمل هذه الطريقة فقط مع المتغيرات العامة المعلنة عبر var أو المعينة بدون كلمة مفتاحية. let و const لا تنشئ خصائصًا للكائن window (فهي تعيش في نطاق الكتلة).