هنعمل أول برنامج صغير فيه تفاعل حقيقي مع المستخدم. هدفنا بسيط: نعمل برنامج آلة حاسبة صغير بيجمع رقمين.

The Goal: A Simple Calculator

عايزين نعمل برنامج يشتغل بالخطوات دي:

  1. يطلب من المستخدم يدخل الرقم الأول.
  2. يطلب من المستخدم يدخل الرقم التاني.
  3. يجمع الرقمين دول.
  4. يعرض الناتج على الشاشة.

Step 1: Getting Input from the User with window.prompt()

لحد دلوقتي، كنا بنحط القيم بتاعتنا بشكل ثابت (static) جوه الكود، زي var x = 5;. لكن في التطبيقات الحقيقية، كتير من البيانات بتيجي من المستخدم نفسه.

عشان ناخد داتا من المستخدم، بنستخدم فانكشن جاهزة اسمها window.prompt(). الفانكشن دي بتعمل حاجة شبه alert، لكنها بتطلع مربع حوار فيه مكان للكتابة (input field).

window.prompt("Enter the first number:");

الـ prompt بتقبل string كـ argument، والـ string ده هو الرسالة اللي بتظهر للمستخدم عشان توضح له إيه المطلوب منه.

Step 2: Capturing the Returned Value

طيب، القيمة اللي المستخدم بيكتبها دي بتروح فين؟ الـ prompt فانكشن بترجع (returns) القيمة اللي المستخدم دخلها. عشان نقدر نستخدم القيمة دي، لازم نستقبلها في متغير (variable).

// The value entered by the user will be stored in the `num1` variable
var num1 = window.prompt("Enter the first number:");
 
var num2 = window.prompt("Enter the second number:");

كده بعد ما الكود ده يشتغل، هيبقى معانا متغيرين num1 و num2 شايلين القيم اللي المستخدم دخلها.

The Problem: prompt() Always Returns a String

هنا بتظهر مشكلة مهمة جدًا. الـ prompt() فانكشن، بغض النظر عن اللي المستخدم كتبه، دايمًا بترجع القيمة كـ string.

يعني لو المستخدم كتب الرقم 10، الـ prompt هترجع الـ string "10" مش الـ number 10.

إيه تأثير ده على البرنامج بتاعنا؟ لو جينا نجمع الرقمين دلوقتي:

var result = num1 + num2;

بما إن num1 و num2 هما strings، علامة الزائد (+) هتشتغل كـ concatenation (لصق) مش كـ addition (جمع).

فلو المستخدم دخل 10 و 10 تاني، الناتج اللي هيطلع هيكون "1010" مش 20.

Step 3: Type Casting with Number()

عشان نحل المشكلة دي، لازم نعمل Type Casting (أو Type Conversion)، يعني نحول القيم اللي جاية من الـ prompt من string لـ number بشكل صريح.

بنعمل ده باستخدام فانكشن جاهزة اسمها Number(). الفانكشن دي بتاخد أي قيمة وبتحاول تحولها لرقم.

// Wrap the prompt in the Number() function to convert the result
var num1 = Number(window.prompt("Enter the first number:"));
 
var num2 = Number(window.prompt("Enter the second number:"));
 
// Now `num1` and `num2` are actual numbers
var result = num1 + num2;

دلوقتي، لما المستخدم يدخل 10 و 10، المتغير result هيشيل القيمة 20 بشكل صحيح.

Step 4: Displaying the Output

آخر خطوة هي إننا نعرض الناتج النهائي للمستخدم. ممكن نعمل ده ببساطة عن طريق إننا نحط الناتج في innerHTML بتاع عنصر معين في الصفحة.

<!-- In our HTML file -->
<h1 id="demo"></h1>
// In our JS file
document.getElementById('demo').innerHTML = result;

Part 2: Quick Revision on Core Concepts

دي فرصة كويسة إننا نراجع على المفاهيم الأساسية اللي مرت علينا:

  • الـ var vs. let/const: اتفقنا إننا هنستخدم var في المرحلة دي عشان نفهم أساسيات اللغة، لكن في الشغل الحقيقي، let و const هما الأفضل لأنهم بيحترموا الـ Block Scope.
  • الـ Primitive Data Types: الأنواع الأساسية اللي اتعاملنا معاها هي: string, number, boolean, undefined, null.
  • الـ typeof Operator: بنستخدمه عشان نعرف نوع أي متغير.
  • الـ Loosely Typed & Dynamic: الجافا سكريبت لغة loosely typed (مش بنحدد نوع المتغير) و dynamic (نوع المتغير ممكن يتغير).
  • الـ Type Coercion: تحويل أنواع البيانات، سواء implicit (تلقائي من اللغة) أو explicit (بطلب صريح مننا زي استخدام Number()).
  • الـ + Operator vs. Other Operators: علامة + هي الوحيدة اللي ممكن تشتغل كلصق مع الـ strings. باقي العمليات الحسابية (-, *, /) بتحاول دايمًا تحول الأطراف لأرقام.

Notes

  • الـ Console Colors: في الـ developer tools بتاعة المتصفح (زي Chrome)، الـ console بتميز بين أنواع البيانات المختلفة بالألوان. الأرقام غالبًا بتظهر باللون الأزرق، والـ strings باللون الأسود. دي طريقة سريعة تعرف بيها نوع القيمة اللي بتطبعها من غير ما تحتاج تكتب typeof.
  • الـ Error Handling for Number(): إيه اللي يحصل لو المستخدم دخل Ahmed بدل رقم في الـ prompt بتاعنا؟ Number("Ahmed") هترجع NaN (Not-a-Number). في التطبيقات الحقيقية، المفروض نعمل check على الناتج ده باستخدام isNaN() ونطلع رسالة للمستخدم لو دخل قيمة غلط.
let num = Number(prompt("..."));
if (isNaN(num)) {
	alert("Please enter a valid number!");
} else {
	// ... proceed with calculation
}
  • الـ Validation Attributes in MVC .NET: لو عملية التحويل دي فشلت (مثلًا المستخدم كتب abc في حقل متوقع فيه int)، الـ Model Binding مش بيرمي exception على طول، بدل كده هو بيسجل Model Error. تقدر بعد كده في الكود بتاعك تعمل check على الـ ModelState.IsValid. ده بيخلي عملية الـ validation والـ error handling في .NET منظمة جدًا.
    // In an ASP.NET Controller Action
    public IActionResult Create(ProductViewModel model)
    {
        if (!ModelState.IsValid)
        {
            // If binding/validation fails, return the view with error messages
            return View(model);
        }
        // ... proceed with valid data
    }

الفكرة الأساسية واحدة: الداتا اللي جاية من المستخدم لازم دايمًا نعملها validation و parsing قبل ما نثق فيها ونستخدمها في أي عمليات.