المستوى: مبتدئ. لو بتكتب if (x == 0) وفاكر إنها بتقارن الأرقام وبس، اللي جاي هنا هيوريك ليه السطر ده ممكن يكسر تطبيقك في حالات ما تتوقعهاش.
الفرق بين == و === في جافاسكريبت
الخلاصة قبل أي شرح: استخدم === كإعداد افتراضي، وسيب == لحالات نادرة تعرفها بالظبط. السبب إن == بيحوّل الأنواع من ورا ظهرك قبل ما يقارن، وده بيطلّع نتائج غريبة زي '' == 0 اللي بترجع true.
المشكلة باختصار
في جافاسكريبت فيه طريقتين للمقارنة: == (المرن) و=== (الصارم). الاتنين شكلهم متقارب، بس بيتصرفوا بشكل مختلف تمامًا. اللي بيحصل فعلاً إن == بيحاول "يوفّق" بين النوعين المختلفين قبل المقارنة، فبيطلّع نتائج بتضحك من غير ما تضحك. النتيجة: باجات صامتة صعب تلاقيها.
الأول نبدأ بمثال بسيط
تخيّل عندك بوابين على مدخل مبنى. البواب الأول (وده ==) بيعرف الناس "بالتقريب": لو حد قاله "أنا رقم صفر"، وحد تاني جه من غير ما يقول حاجة (نص فاضي)، البواب يقول "معلش، الاتنين قريبين من بعض، دخّلهم على إنهم نفس الشخص". النتيجة إنه بيتخدع.
البواب التاني (وده ===) بيطلب البطاقة. بيبص على النوع والقيمة مع بعض: لازم يكونوا "رقم" و"رقم"، وبنفس القيمة. لو واحد "نص" وواحد "رقم"، يرفض على طول. البواب ده مبيتخدعش، وده اللي انت عايزه في 95% من الحالات.
دلوقتي المفهوم العلمي: التحويل الضمني
لما تكتب == بين نوعين مختلفين، جافاسكريبت بتعمل حاجة اسمها التحويل الضمني للنوع (Type Coercion): بتحوّل أحد الطرفين عشان يبقى نفس نوع الطرف التاني، وبعدين تقارن. في حالة نص مقابل رقم، بتحوّل النص لرقم. فـ '' == 0 بتتحوّل لـ Number('') == 0، والنص الفاضي بيتحوّل لـ 0، فتبقى 0 == 0 وترجع true.
أما === فبيقارن من غير أي تحويل. لو النوعين مختلفين، النتيجة false على طول، خلاص. ده اللي خلّاه أوضح وأأمن.
// == بيحوّل الأنواع قبل المقارنة (مفاجآت)
console.log('' == 0); // true → Number('') يساوي 0
console.log('0' == false); // true → الاتنين بيتحوّلوا لـ 0
console.log([] == ![]); // true → [] بيتحوّل لـ '' ثم لـ 0
console.log(null == undefined); // true
// === بيقارن النوع والقيمة معًا (متوقّع)
console.log('' === 0); // false
console.log('0' === false); // false
console.log(0 === 0); // true
مثال من الواقع بيكسر تطبيقك
افترض عندك متجر، وبتتحقق من كمية المنتج اللي المستخدم كتبها في حقل الإدخال: