اذهب إلى المحتوى

السؤال

نشر

السادة الافاضل 

مرفق الكود 

التالى 

var value1 = "32";
var value2 = 10;
var value3 = 7;
var sum = value1 + value2 + value3;
console.log(sum);

بيرجع 32107

و الكود التالى بيرجع 

var value1 = 32;
var value2 = 10;
var value3 = 7;
var sum = value1 + value2 + value3;
console.log(sum);

بيرجع 49

الكود الاول تعامل مع جميع الارقام على انها من النوع STRING

بينما الكوت الثانى تعامل مع جميع الارقام ك NUMBER 

مع العلم عند الرجوع الى 

Type coercion

وكتابه 

true == "1"

بيكون الناتج true

ويتم تحويل نوع البايانت من string to number  بشكل ضمنى 

لماذا لايتم مثل هذا فى المثال الاول بناءا على Type coercion

Recommended Posts

  • 0
نشر

هذا الأمر بالفعل يسبب إلتباس وخطأ وهو يكمن في الفرق بين التحويل الضمني (Type Coercion) عند استخدام عامل الجمع و المقارنة بعامل المقارنة ==.

ففي JavaScript يمتلك عامل الجمع + وظيفتين مختلفتين تماما ويتم تحديد الوظيفة بناء على نوع البيانات :

  • الجمع الحسابي (Addition): إذا كان الطرفين أرقاما.
  • الدمج النصي (Concatenation): إذا كان أحد الطرفين أو كلاهما نصا (String).

ففي JavaScript للنصوص الأولوية القصوى عند استخدام عامل + فبمجرد أن يرى المحرك نصا واحدا في العملية فإنه يقوم بتحويل كل ما يليه إلى نصوص ودمجها.

ففي مثالك الأول:

  • value1 هو نص "32".
  • وعند تنفيذ value1 + value2 تصبح العملية "32" + 10.
  • بسبب وجود النص يتم تحويل 10 إلى "10" والنتيجة "3210".
  • ثم "3210" + 7 تصبح "32107".

ولاحظ أن العملية ستختلف بناء على ترتيب الأرقام والنصوص فمثلا :

var value1 = 32;
var value2 = 10;
var value3 = "7";
var sum = value1 + value2 + value3;
console.log(sum);

ستجد النتيجة 427 وذلك لأنه أولا تم جمع 32 و 10 لأنهم أرقام والناتج هو 42 ومن ثم يتم جمع 42 مع النص 7 ليصبح الناتج 427 .

أما بخصوص سؤالك لماذا في true == "1" يتم التحويل لرقم بينما في المثال الأول لم يحدث ذلك فإن الإجابة تكمن في أن قواعد التحويل تختلف باختلاف العامل (Operator):

فعند استخدام == لمقارنة أنواع مختلفة تتبع JavaScript خوارزمية محددة تسمى (Abstract Equality Comparison Algorithm) :

فإذا تم مقارنة Boolean مع أي نوع آخر يتم تحويله أولا إلى Number (أى true تصبح 1).

وإذا تم مقارنة Number مع String يتم تحويل النص إلى رقم.

ولذلك فإن true == "1" تتحول إلى 1 == 1 والنتيجة true.

وفي حالة الجمع المحرك لا يحاول تحويل النص إلى رقم لأن الدمج النصي هو السلوك الافتراضي لعامل الجمع + وهو يفترض أنك تريد بناء نص طويل وليس بالضرورة إجراء عملية حسابية.

وستلاحظ الفرق عند إستخدام عامل الطرح "-" فعامل الطرح لا يعمل إلا مع الأرقام ولذلك فإنه يجبر التحويل إلى رقم وليس سلسة نصية. 

  • 0
نشر

الفرق الذي لاحظته في الأمثلة يعود إلى آلية التحويل الضمني (Type coercion) في جافاسكريبت، ولكن هناك عند وجود عملية جمع (+)، إذا كان أحد الطرفين سلسلة نصية (string)، فإن جافاسكريبت تحول الطرف الآخر تلقائيًا إلى string أيضًا وتقوم بعملية الربط النصي (concatenation) بدل الجمع العددي.

في المثال الأول:

 

var value1 = "32"; // string
var value2 = 10;   // number
var value3 = 7;    // number
var sum = value1 + value2 + value3;
console.log(sum);  // "32107"

بسبب أن value1 نصية، عند كتابة value1 + value2، يحوّل value2 إلى نص ويجمعهم نصيًا  "3210". ثم يضاف value3  "32107".

في المثال الثاني: كل القيم أرقام، لذلك يتم الجمع الطبيعي  32 + 10 + 7 = 49.

لتجنب هذا السلوك، يمكنك استخدام

Number() 

لتحويل أي قيمة نصية إلى رقم قبل الجمع:

 

var sum = Number(value1) + value2 + value3;
console.log(sum); // 49

بالتوفيق

  • 0
نشر

في الحقيقة عملية الجمع + لها سلوك مزدوج فهي تستخدم لجمع الأرقام ولربط النصوص أيضا وهو ما يعرف بال concatenation وعندما يكون أحد المعاملات نصا (string) يحول JavaScript جميع القيم إلى نصوص ويربطها بدلا من جمعها رياضيا  لذلك فإنّ:

"32" + 10 + 7

سينتج:

"32107"

أما في مقارنة المساواة == التي ذكرتها:

true == "1"

فالوضع مختلف تماما لأن عملية == لا تدعم ربط النصوص فيحاول JavaScript هنا إيجاد أرضية مشتركة بتحويل كلا الطرفين إلى أرقام ف true يصبح 1 و"1" يصبح 1 فتكون المقارنة صحيحة والقاعدة الأساسية أنه عند استخدام + مع نص يحدث تحويل إلى نصوص (String Coercion) بينما في العمليات الأخرى ك (==, -, *, /) يحدث تحويل إلى أرقام (Numeric Coercion).

ولتجنب هذا يمكنك استخدام Number(value1) أو parseInt(value1) أو العملية الأحادية +value1 لتحويل النص إلى رقم قبل الجمع، أو استخدم === بدلا من == لتجنب Type Coercion في المقارنات.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...