أقصر سؤال يفصل مبتدئ جافاسكريبت عن متقنها — وأحد
أثبت أسئلة المقابلات: ما الفرق بين == و ===؟ والأهم: لماذا ستكتب
الثلاثية دائمًا بعد هذا المقال؟
الفكرة في سطرين
===(الصارمة): تقارن القيمة والنوع معًا — نوعان مختلفان؟ النتيجةfalseفورًا، بلا ألاعيب.==(المرنة): إن اختلف النوعان حوّلت أحدهما للآخر ضمنيًا ثم قارنت — وهنا تبدأ المفاجآت.
"5" === 5 // false — نص لا يساوي رقمًا، انتهى
"5" == 5 // true! — حوّلت النص لرقم قبل المقارنة
معرض العجائب: لماذا لا يثق أحد بـ ==
قواعد التحويل الضمني معقدة لدرجة أن نتائجها تبدو نكاتًا:
0 == "" // true (كلاهما يتحول لـ 0)
0 == "0" // true
"" == "0" // false 🤯 (نصان — لا تحويل — مختلفان!)
false == "0" // true
null == 0 // false (null لا تتحول هنا)
" \t\n" == 0 // true (المسافات البيضاء → 0)
[] == false // true
[[]] == false // true 😵
لاحظ الكارثة المنطقية: 0 == "" و0 == "0" صحيحتان لكن "" == "0"
خاطئة — المساواة المرنة ليست علاقة متعدية أصلًا. قواعد لا يحفظها أحد
عمليًا = أخطاء تختبئ بهدوء في الشروط.
المقارنة الصارمة تمسح كل هذا الجدول: كل ما سبق false ببساطة لأن الأنواع
مختلفة.
الاستثناء الوحيد المحترم: x == null
توأم الغياب null وundefined تحدثنا عنهما
بتفصيل كامل هنا — والمساواة المرنة تعتبرهما
متساويين ولا تساوي بهما أي شيء آخر:
x == null
// true فقط إذا كانت x هي null أو undefined — لا 0 ولا "" ولا false
يعني if (x == null) تختصر if (x === null || x === undefined) بأمان
تام. هذا الاستخدام الوحيد الذي يقبله المحترفون لـ == — وحتى هو صار أقل
حاجة مع ?? و?. الحديثتين.
حدود === نفسها (لتكتمل الصورة)
الكائنات: مرجع لا محتوى
{ a: 1 } === { a: 1 } // false — كائنان مختلفان بالذاكرة
[1, 2] === [1, 2] // false — نفس القصة
const a = { x: 1 };
const b = a;
a === b // true — نفس الكائن الواحد
هذا سلوك اللغة مع الكائنات عمومًا (وهو نفسه سرّ حلقة useEffect اللانهائية في React!).
حالتا NaN والأصفار — وObject.is
NaN === NaN // false! الوحيدة التي لا تساوي نفسها
Object.is(NaN, NaN) // true
Number.isNaN(x) // الفحص العملي المعتمد
0 === -0 // true
Object.is(0, -0) // false (تفرقة نادرة الأهمية)
Object.is مساواة ثالثة أدق في هاتين الحالتين الهامشيتين — اعرفها
للمقابلات، واستعمل === لليوميات.
قائمة تحقّق سريعة
- اكتب
===و!==دائمًا — افتراضك الدائم بلا تفكير. - الاستثناء المقبول الوحيد:
x == nullلفحص الغيابين معًا. - كائنات ومصفوفات؟ المقارنة بالمرجع — قارن المحتوى بنفسك.
NaNتُفحص بـNumber.isNaNحصرًا.- فعّل ESLint بقاعدة
eqeqeqفيصير النسيان مستحيلًا.
الخلاصة
=== تقارن بصدق: نفس النوع ونفس القيمة أو لا. == تجاملك بتحويلات خفية
قواعدها أغرب من أن تُحفظ — والمجاملات في الكود تنتهي أخطاءً صامتة.
ثلاثية دائمًا، و== null رخصتك الوحيدة.
رسّخ الأساس في مسار جافاسكريبت بالعربي، وأكمل الثلاثية الذهبية مع الفرق بين var و let و const و الفرق بين undefined و null — وإن أردت لغة تمنع هذا الصداع من أصله فاقرأ الفرق بين JavaScript و TypeScript.