أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالمناهج والباقات
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • المناهج والباقات
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالمناهجالمدونةالدخول
البرمجة بالعربي

Type Coercion في JavaScript للمبتدئ: ليه "5" + 3 بتطلّع "53" و"5" - 3 بتطلّع 2

مبتدئ١٧ يونيو ٢٠٢٦5 دقائق قراءة
Type Coercion في JavaScript للمبتدئ: ليه "5" + 3 بتطلّع "53" و"5" - 3 بتطلّع 2

هذا المقال لمستوى: مبتدئ. لو لسه بتتعلم JavaScript وحَيّرك إن نفس القيمتين بيطلّعوا نتيجتين مختلفتين حسب العلامة اللي بينهم، ده المقال اللي يفك اللخبطة دي من جذورها.

ليه "5" + 3 بتطلّع "53" بينما "5" - 3 بتطلّع 2؟

لو كتبت "5" + 3 في JavaScript وانتظرت 8، هتتصدم لما تلاقي الناتج "53". وبعدها تكتب "5" - 3 وتلاقيه 2 بالظبط. نفس الرقمين، علامة مختلفة، عالمين مختلفين. ده مش عشوائي، وده مش bug. اسمه Type Coercion، يعني التحويل الضمني للأنواع، وفهمه هيوفّر عليك ساعات من مطاردة بوجات مش بتظهر في رسالة خطأ.

المشكلة باختصار

JavaScript لغة فيها أنواع بيانات: نص (string)، رقم (number)، وغيرهم. لكنها مش بتوقفك لما تخلط بينهم. بدل ما ترمي خطأ، بتحاول تخمّن قصدك وتحوّل نوع لنوع تاني من ورا ضهرك. المشكلة إن التخمين ده مفيد أوقات، وبيكسر حساباتك أوقات تانية. وأخطر حاجة إنه بيحصل بصمت، من غير أي تحذير.

كود JavaScript على شاشة داكنة يوضّح التعامل مع أنواع البيانات والتحويل الضمني بين النص والرقم

يعني إيه Type Coercion؟ المثال الأول

تخيّل كاشير في سوبر ماركت. لو إديته صنفين وقلتله "اجمعهم"، هيحط واحد ورا التاني في كيس واحد. لكن لو إديته فلوس وقلتله "اطرح الخصم"، هيحسبها أرقام عادي. الكاشير بيقرأ نية العملية من العلامة اللي قلتهاله، مش من نوع اللي في إيدك.

JavaScript بتعمل نفس الحاجة. علامة الجمع + ليها معنيين: تجميع نصوص (concatenation) أو جمع أرقام. لمّا تلاقي طرف واحد على الأقل نص، بتقرّر إنك قصدك تجمّع نصوص، فبتحوّل الرقم 3 لنص "3" وتلزقه. لكن علامة الطرح - ليها معنى واحد بس: عملية حسابية. مفيش حاجة اسمها "طرح نصوص"، فبتحوّل النص "5" لرقم 5 وتطرح عادي.

دلوقتي الشرح العلمي بدقة: المحرّك بيطبّق عملية مجرّدة اسمها ToPrimitive على كل طرف، وبعدها العلامة بتفرض اتجاه التحويل. علامة + لو أي طرف طلع نص، بتستدعي ToString على الطرف التاني. أي علامة حسابية تانية (-، *، /، %) بتستدعي ToNumber على الطرفين. القاعدة دي مكتوبة حرفيًا في مواصفة ECMAScript تحت عمليات ToNumber وToString.

شاشة محرر أكواد تعرض أسطر JavaScript ملوّنة تمثّل عمليات الجمع والطرح بين نص ورقم

الكود اللي يثبتلك الكلام

افتح أي console (المتصفح أو Node) وجرّب ده بنفسك. كل سطر معاه ناتجه:

JavaScript
console.log("5" + 3);          // "53"   نص، لأن + لقى نص
console.log("5" - 3);          // 2       رقم، لأن - حسابية
console.log("5" * "2");        // 10      الاتنين اتحولوا لأرقام
console.log(typeof ("5" + 3)); // "string"
console.log(typeof ("5" - 3)); // "number"
console.log(true + 1);         // 2       true بتتحول لـ 1
console.log("" == 0);          // true    == بيعمل coercion كمان

الفخ الحقيقي: مجموع حقول الفورم

السيناريو ده بيحصل في أي مشروع فيه فورم. أي قيمة بتيجي من <input> بتكون نص دايمًا، حتى لو المستخدم كتب أرقام. تخيّل عندك 3 حقول سعر، كل واحد فيه "100"، والمفروض المجموع 300:

JavaScript
const prices = ["100", "100", "100"]; // زي اللي جاي من inputs

let total = 0;
for (const p of prices) {
  total += p;          // + لقى نص، فبيلزق بدل ما يجمع
}
console.log(total);    // "0100100100"  ←  9 خانات بدل 300

// الإصلاح: حوّل لرقم بصراحة
let fixed = 0;
for (const p of prices) {
  fixed += Number(p);  // ToNumber صريح
}
console.log(fixed);    // 300  ✓ صح

لاحظ الفرق: النسخة الأولى طلّعت سلسلة من 9 خانات قيمتها صفر فعليًا في حساباتك، والمستخدم هيشوف رقم غريب في الفاتورة. النسخة التانية صح لأننا أجبرنا التحويل بـ Number() قبل الجمع. نفس النتيجة تتحقق بـ parseInt(p, 10) أو بعلامة الزائد الأحادية +p.

القاعدة الواحدة اللي تحفظها

ركّز في جملة واحدة: علامة + بس هي اللي بتفضّل النصوص. أي علامة حسابية تانية بتفضّل الأرقام. لو حفظت دي، 90% من مفاجآت الـ coercion هتبقى متوقّعة عندك. ولو عايز تتجنّب اللعبة كلها في المقارنات، استخدم === بدل ==، لأن === ما بيعملش تحويل أنواع خالص وبيقارن النوع والقيمة زي ما هما.

الـ trade-off

التحويل الضمني بيوفّرلك كتابة. تقدر تكتب "العمر: " + age من غير ما تحوّل age بإيدك، وده مريح في بناء النصوص. الثمن: نفس الراحة دي بتخبّي بوجات حسابية بتعدّي بصمت لحد ما تظهر في فاتورة أو تقرير. المكسب سطور أقل، الخسارة وضوح أقل وأخطاء مش بتطلع في رسالة. القاعدة العملية: استخدم التحويل الضمني في بناء النصوص فقط، وحوّل بصراحة بـ Number() في أي عملية حسابية.

متى لا تشغّل بالك بالموضوع ده

لو بتستخدم TypeScript وبتفعّل فحص الأنواع، الكومبايلر هيمسكلك خلط النص بالرقم قبل ما يشتغل أصلًا، فالخطر بيقل جدًا. وكمان لو بتعمل validation وتحويل لكل المدخلات عند حدود النظام (وقت ما تيجي من الفورم أو الـ API مباشرة)، فبقية الكود بيشتغل بأرقام نضيفة ومش هتقابل المشكلة. الموضوع ده بيوجع أكتر في JavaScript عادي بدون أنواع، ومع بيانات جاية من inputs أو من JSON.

الخطوة التالية

دلوقتي افتح أقرب مكان في كودك بتجمع فيه قيمة جاية من input أو req.body. لو لقيتها بتتجمع بـ + من غير Number() قبلها، ده مكان فيه bug مستني. لفّها بـ Number() أو parseInt، وجرّب تبعت "100" ثلاث مرات وتشوف المجموع طلع 300 ولا "0100100100".

المصادر

  • MDN Web Docs — Type coercion: developer.mozilla.org/en-US/docs/Glossary/Type_coercion
  • MDN Web Docs — Equality comparisons and sameness (== مقابل ===): developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness
  • ECMAScript Language Specification (ECMA-262) — Abstract Operations: ToPrimitive، ToNumber، ToString: tc39.es/ecma262
  • MDN Web Docs — Addition (+) operator: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Addition

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة