هنوضح إزاي اللغة بتفكر وبتتعامل مع أنواع البيانات المختلفة، خصوصًا في العمليات الحسابية.

The Double Life of the + Operator

علامة الزائد (+) في الجافا سكريبت ليها شخصيتين مختلفتين:

  1. الـ Addition (الجمع): لما بتتحط بين رقمين، بتشتغل كعملية جمع حسابية عادية.
let x = 3 + 4; // x will be 7
  1. الـ String Concatenation (اللصق): لما بتتحط بين اتنين string، بتشتغل كعملية لصق أو تجميع، بتلزق الـ strings في بعض.
let x = "Pop" + " Corn"; // x will be "Pop Corn"

The Rules of + Operator Coercion

اللخبطة بتبدأ لما نخلط أنواع البيانات. إيه اللي بيحصل لما نستخدم علامة + بين string و number؟

القاعدة بسيطة: لو طرف واحد من أطراف علامة + كان string، الجافا سكريبت بتقلب العملية كلها لـ concatenation (لصق). هي بتحول الطرف التاني (اللي مش string) لـ string هي كمان، وبعدين تلزقهم في بعض.

أمثلة:

// String + Number -> Concatenation
let result1 = "3" + 4; // "3" + "4" -> "34"
 
// Number + String -> Concatenation
let result2 = 3 + "4"; // "3" + "4" -> "34"

Order of Operations Matters

ترتيب العمليات مهم جدًا وبيفرق في الناتج. الجافا سكريبت بتمشي على العمليات من الشمال لليمين.

مثال 1:

let result = 4 + 4 + "4"; // What is the output?

التحليل (من الشمال لليمين):

  1. 4 + 4: دول رقمين، يبقى العملية جمع. الناتج 8 (من نوع number).
  2. 8 + "4": دلوقتي بقى عندنا number زائد string، يبقى العملية هتقلب لصق. الناتج "84" (من نوع string). الناتج النهائي: "84"

مثال 2 (العكس):

let result = "4" + 4 + 4; // What is the output?

التحليل (من الشمال لليمين):

  1. "4" + 4: ده string زائد number، يبقى لصق. الناتج "44" (من نوع string).
  2. "44" + 4: دلوقتي بقى عندنا string زائد number تاني، يبقى برضه لصق. الناتج "444" (من نوع string). الناتج النهائي: "444"

Other Arithmetic Operators

على عكس الـ +، باقي العمليات الحسابية (-, *, /, %) ليها شخصية واحدة بس: هي عمليات حسابية وفقط.

القاعدة: أي عملية حسابية غير الـ + بتحاول دايمًا تحول الأطراف بتاعتها لـ numbers قبل ما تنفذ العملية. العملية دي بنسميها Implicit Conversion (تحويل ضمني).

let result = "4" * "5"; // What happens here?

الجافا سكريبت بتشوف إن دي عملية ضرب، فبتقول: “أنا معرفش أضرب strings، بس الـ string ’ 4’ ده شبه الرقم 4، والـ string ‘5’ ده شبه الرقم 5. خلاص أنا هحولهم لأرقام الأول وبعدين أضرب”.

التحليل الضمني:

  1. "4" تتحول للرقم 4.
  2. "5" تتحول للرقم 5.
  3. 4 * 5 الناتج 20 (من نوع number). الناتج النهائي: 20 (وهيظهر باللون الأزرق في الـ console).

The Number() Conversion Function

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

  • Number("4") 4
  • Number(true) 1
  • Number(false) 0
  • Number("") (empty string) 0
  • Number(" ") (string with space) 0
  • Number(null) 0

What if Conversion Fails?

طب إيه اللي يحصل لو ادينا Number() حاجة مينفعش تتحول لرقم أصلًا، زي Number("Ahmed")؟

في الحالة دي، الفانكشن بترجع قيمة خاصة اسمها NaN (اختصار لـ Not-a-Number).

الـ NaN هي قيمة غريبة جدًا في الجافا سكريبت:

  • هي اختصار لـ “ليس رقمًا”.
  • لكن لو سألت عن نوعها (typeof NaN)، هتقولك إنها number! هي “special number” بيستخدم للدلالة على إن عملية حسابية فشلت.
  • أي عملية حسابية بتدخل فيها NaN كطرف، الناتج بتاعها دايمًا بيكون NaN.
    • 4 * NaN NaN
    • 4 + NaN NaN

مثال:

let result = 4 * "Ahmed";

التحليل:

  1. دي عملية ضرب، فهتحاول تحول "Ahmed" لرقم.
  2. الـ Number("Ahmed") هترجع NaN.
  3. المعادلة هتبقى 4 * NaN.
  4. الناتج النهائي هيكون NaN.

Notes

  • الـ Explicit vs. Implicit Conversion:

    • الـ Explicit Conversion: لما أنت كمبرمج بتطلب التحويل بنفسك صراحةً، زي Number("5") أو String(10).
    • الـ Implicit Conversion: لما اللغة هي اللي بتعمل التحويل تلقائيًا من ورا ضهرك عشان تنفذ عملية معينة، زي "5" * 2. فهم الـ Implicit Conversion في الجافا سكريبت مهم جدًا عشان تتجنب نتائج غير متوقعة.
  • الـ The Unary + Operator: فيه طريقة مختصرة عشان تعمل explicit conversion لـ number وهي إنك تحط علامة + قبل القيمة.

let x = +"5"; // x is now the number 5
let y = +"";   // y is now the number 0

الـ Unary + operator بيحاول يحول اللي بعده لرقم بالظبط زي Number() فانكشن.

  • الـ NaN’s Weird Equality: NaN هي القيمة الوحيدة في الجافا سكريبت اللي مش بتساوي نفسها.
    • الـ NaN === NaN false!
    • عشان كده، عشان تتأكد لو قيمة معينة هي NaN ولا لأ، مينفعش تعمل myVar === NaN. الطريقة الصح هي إنك تستخدم الفانكشن الجاهزة isNaN(myVar).

Relation to .NET

  • الـ No Implicit Coercion for Strings: في C#، مفهوم الـ “implicit string-to-number coercion” ده مش موجود تمامًا. الـ compiler بيمنعك من الأول. لو حاولت تعمل "4" * "5"، هتاخد compile error على طول بيقولك “Operator ’*’ cannot be applied to operands of type ‘string’ and ‘string’“.
  • الـ Explicit Parsing: عشان تحول string لرقم في C#، لازم تعمل explicit parsing باستخدام methods زي int.Parse() أو double.Parse().
int x = int.Parse("4");
int y = int.Parse("5");
int result = x * y; // result is 20
  • الـ Error Handling: لو حاولت تعمل int.Parse("Pop")، الكود مش هيرجع قيمة خاصة زي NaN. بدل كده، هيرمي Exception (تحديدًا FormatException)، وده هيوقف البرنامج لو معملتش try-catch block عشان تتعامل مع الـ exception ده.
  • الصرامة دي في .NET بتجبر المبرمج إنه يفكر في كل الاحتمالات ويتعامل مع الأخطاء بشكل صريح، وده بيخلي التطبيقات أكثر استقرارًا وموثوقية، على عكس جافا سكريبت اللي بتحاول “تمشي الدنيا” حتى لو النتائج ممكن تكون غريبة.