١٥ يونيو ٢٠٢٠

العاملات الأساسية والرياضيات #

نعرف الكتير من المعاملات الحسابية من التعليم الأساسي في المدارس مثل عامل الإضافة ‘+’ , والضرب ‘*’ والطرح ‘-’ وخلافه

في هذا الفصل سنبدأ بالعاملات الحسابية البسيطة ثم سنركز على النواحي المحددة بالنسبة للغة جافاسكريبت والتي لم يتم تغطيتها برياضيات الحساب في المدرسة

#مصطلحات: أحادي، ثنائي ، ومعامل

قبل ما ان نكمل، فلنفهم جيدا بعض المصطلحات

*معامل * – هو ما يتم تطبيق العاملات الحسابية عليه. على سبيل المثال، عند ضرب 2 * 5 يوجد معاملات اثنان: المعامل الأيسر “5” والمعامل الأيمن “2” . أحيانا الناس يسمونها "عوامل متغيرة " بدلا من "معاملات " العامل الحسابي يكون أحاديا إذا كان لديه معامل واحد فقط. على سبيل المثال عامل الطرح الأحادي ‘-’ يعكس إشارة الرقم:

```js run
let x = 1;

*!*
x = -x;
*/!*
alert( x ); // -1, unary negation was applied
```
العامل الحسابي يكون ثنائيا إذا كان لديه معاملين حسابيين  اثنين. نفس الشيء بالنسبة لعامل الطرح الحسابي أيضا: 

```js run no-beautify
let x = 1, y = 3;
alert( y - x ); // 2, binary minus subtracts values
```

بشكل رسمي، في الأمثلة السابقة كان لدينا عاملين حسابيين مختلفين يشتركان في نفس الرمز: عامل النفي يعكس إلإشارة وعامل الطرح , عامل ثنائي يقوم يطرح رقم من آخر 

#الرياضيات

العمليات الحسابية التالية مدعومة:

  • الإضافة “+”
  • الطرح “-”
  • الضرب “*”
  • القسمة “/”
  • باقي القسمة “%”
  • الضرب الأسي “**”

العوامل الحسابية الأربع الأوئل واضحين بينما باقي القسمة “%” والضرب الأسي “**” بحاجة إلى بعض الإيضاح حولهم

بافي القسمة %

عامل باقي القسمة “%” بالرغم من شكله إلا أنه لا صلة له بالنسبة المئوية

ناتج a % b هو [باقي قسمة] الرقم “a” على الرقم “b” (https://en.wikipedia.org/wiki/Remainder)

على سبيل المثال:

alert( 5 % 2 ); // 1, a remainder of 5 divided by 2
alert( 8 % 3 ); // 2, a remainder of 8 divided by 3

الضرب الأسي **

عامل الضرب الأسي a ** b يقوم بضرب الرقم a في نفسه عدد b من المرات

على سبيل المثال:

alert( 2 ** 2 ); // 4  (2 multiplied by itself 2 times)
alert( 2 ** 3 ); // 8  (2 * 2 * 2, 3 times)
alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2, 4 times)

من الناحية الرياضياتية الضرب الأسي يستخدم أيضا مع الأرقام غير الصحيحة. على سبيل المثال الجذر التربيعي هو ضرب أسي بقيمة 1/2:

alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root)
alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root)

إضافة الكلمات وسلاسل الحروف بعامل الإضافة +

هيا نتعرف على مميزات عوامل اللغة جافاسكريبت والتي تتجاوز الحساب المدرسي

عادة، عامل الإضافة “+” يقوم بجمع الأرقام

لكن لو العامل الحسابي الثنائي “+” تم تطبيقه على الكلمات فإنه يقوم بدمجهم معا:

let s = "my" + "string";
alert(s); // mystring

لاحظ أنه إذا كان أي من المعاملات عبارة عن كلمة فإنه يتم تحويل الآخر إلى كلمة أيضا

على سبيل المثال:

alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"

أرأيت، لا يهم إذا كان المعامل الأول أو الثاني عبارة عن كلمة

مثال آخر أكثر تعقيدا:

alert(2 + 2 + '1' ); // "41" and not "221"

هنا العوامل الحسابية تعمل بعد الأخرى. عامل الإضافة الأول “+” يقوم بجمع الرقمين فيصبح ناتجهمها “4” ثم يقوم عامل الإضافة الثاني “+” بدمج “4” و “1” في كلمة واحدة فتصبح الناتج النهائي مثل 4 + '1' = 41.

عامل الإضافة الثنائي “+” هو العامل الوحيد الذي يدعم الكلمات بهذه الطريقة العوامل الحسابية الأخرى تعمل فقط مع الأرقام ودائما ما تحول المعاملات إلى أرقام

هنا شرح مبسط لعملية الطرح والقسمة:

alert( 6 - '2' ); // 4, converts '2' to a number
alert( '6' / '2' ); // 3, converts both operands to numbers

التحويل العددي ، الأحادي +

إشارة الجمع “+” توجد في شكلين ، الشكل الثنائي كما تم استخدامه من قبل والشكل الأحادي

عامل الإضافة الأحادي أو بكلمات أخرى عامل الزائد “+” الذي يتم تطبيقه على قيمة واحدة لا يؤثر على الأرقام لكن إذا كان المعامل ليس رقما فإن عامل الإضافة الأحادي يحولها إلى رقم

على سبيل المثال:

// No effect on numbers
let x = 1;
alert( +x ); // 1

let y = -2;
alert( +y ); // -2

// Converts non-numbers
alert( +true ); // 1
alert( +"" );   // 0

فهو بالفعل يقوم بنفس عمل دالة Number(...) ولكنه أقصر

فعادة ما يكون هناك حاجة لتحويل الكلمات إلى أرقام على سبيل المثال ، إذا كنا نحصل من خلال استمارة HTML على قيم ،فإنها عادة ما تكون على شكل كلمات ماذا لو أردنا جمعهم سويا ؟

معامل الزائد الثنائي سيقوم بجمعهم ودمجهم ككلمات:

let apples = "2";
let oranges = "3";

alert( apples + oranges ); // "23", the binary plus concatenates strings

فإذا أردنا جمعهم كأرقام ، فإننا بحاجة إلى تحويلهم ثم جمعهم:

let apples = "2";
let oranges = "3";

// both values converted to numbers before the binary plus
alert( +apples + +oranges ); // 5

// the longer variant
// alert( Number(apples) + Number(oranges) ); // 5

من وجهة نظر حسابية أو رياضياتية ، قد تبدو كثرة الزوائد شيئا غريبا لكن بالنسبة للمبرمج فلا يوجد شيء غريب : فالزوائد الأحادية تحول الكلمات إلى أرقام أولا ثم الزائد الثنائية تجمعهم معا

لماذا يتم تطبيق الزوائد الأحادية على القيم قبل الزوائد الثنائية ؟ كما سنرى فإن ذلك بسبب الأسبقية الأعلى

##أسبقية العوامل

إذا كان التعبير يحتوي على أكثر من عامل واحد ، فسيتم تحديد أمر التنفيذ من خلال * أسبقيته * ، أو بعبارة أخرى ، ترتيب الأولوية الافتراضي للعوامل.

من المدرسة ، نعلم جميعًا أنه يجب حساب الضرب في التعبير 1 + 2 * 2 قبل الإضافة. هذا هو بالضبط الأسبقية. ويقال أن الضرب له * أسبقية أعلى من الإضافة.

تلغي الأقواس أي أسبقية ، لذلك إذا لم نكن راضيين عن الترتيب الافتراضي ، فيمكننا استخدامها لتغييره. على سبيل المثال ، اكتب (1 + 2) * 2.

هناك العديد من العوامل في JavaScript. لكل عامل رقم أسبقية مطابق. يتم تنفيذ واحد مع العدد الأكبر أولاً. إذا كانت الأسبقية هي نفسها ، فسيكون أمر التنفيذ من اليسار إلى اليمين.

إليك مقتطف من [جدول الأسبقية] (https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) (لست بحاجة إلى تذكر ذلك ، ولكن لاحظ أن عوامل التشغيل الأحادية أعلى من الخيارات الثنائية المقابلة) منها):

الأسبقية الاسم تسجيل
17 أحادي زائد +
17 نفي أحادي -
16 الأسي **
15 الضرب *
15 تقسيم /
13 إضافة +
13 طرح -
3 الاحالة =

كما نرى ، فإن “unary plus” لها أولوية “17” وهي أعلى من “13” لـ “add” (ثنائي زائد). لهذا السبب ، في تعبير “+ apples + + oranges” ، تعمل الإيجابيات الأحادية قبل الإضافة.

التعيين

دعنا نلاحظ أن المهمة = هي أيضًا عامل. وهي مدرجة في جدول الأسبقية بأولوية منخفضة جدًا لـ 3.

لهذا السبب ، عندما نقوم بتعيين متغير ، مثل x = 2 * 2 + 1 ، تتم الحسابات أولاً ثم يتم تقييم=، وتخزين النتيجة فيx.

let x = 2 * 2 + 1;

alert( x ); // 5

التعيين == إرجاع قيمة

إن حقيقة كونك عامل تشغيل ، وليس بنية لغة “سحرية” لها آثار مهمة.

ترجع معظم عوامل التشغيل في JavaScript قيمة. هذا واضح لـ + و- ، ولكنه ينطبق أيضًا على =.

تؤدي المكالمة x = value إلى كتابةvalue في x * ثم إرجاعها *.

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

let a = 1;
let b = 2;

let c = 3 - (a = b + 1);

alert( a ); // 3
alert( c ); // 0

في المثال أعلاه ، نتيجة التعبير (a = b + 1) هي القيمة التي تم تعيينها لـ a (أي3). ثم يتم استخدامه لمزيد من التقييمات.

كود مضحك ، أليس كذلك؟ يجب أن نفهم كيف يعمل ، لأنه في بعض الأحيان نراه في مكتبات JavaScript.

على الرغم من ذلك ، من فضلك لا تكتب الرمز مثل هذا. مثل هذه الحيل بالتأكيد لا تجعل الشفرة أكثر وضوحًا أو قابلة للقراءة.

التعيينات المتتابعة

: ميزة أخرى مثيرة للاهتمام هي القدرة على التعيين المتتابع

let a, b, c;

a = b = c = 2 + 2;

alert( a ); // 4
alert( b ); // 4
alert( c ); // 4

يتم تقييم التعيينات المتتابعة من اليمين إلى اليسار. أولاً ، يتم تقييم التعبير الموجود في أقصى اليمين 2 + 2 ثم يتم تعيينه للمتغيرات الموجودة على اليسار:c وb وa. في النهاية ، تشترك جميع المتغيرات في قيمة واحدة.

مرة أخرى ، لأغراض سهولة القراءة ، من الأفضل تقسيم هذه الشفرة إلى بضعة أسطر:

c = 2 + 2;
b = c;
a = c;

هذا أسهل للقراءة ، خاصة عند مسح العين للرمز بسرعة.

تعديل في المكان

غالبًا ما نحتاج إلى تطبيق عامل تشغيل على متغير وتخزين النتيجة الجديدة في نفس المتغير.

فمثلا:

let n = 2;
n = n + 5;
n = n * 2;

يمكن تقصير هذا التدوين باستخدام عوامل التشغيل + = و * =:

let n = 2;
n += 5; // now n = 7 (same as n = n + 5)
n *= 2; // now n = 14 (same as n = n * 2)

alert( n ); // 14

توجد معاملات “التعديل والتخصيص” القصيرة لجميع العمليات الحسابية ومعاملات البتات: / = ، - = ، إلخ.

مثل عوامل التشغيل هذه لها نفس الأسبقية للمهمة العادية ، لذلك يتم تشغيلها بعد معظم الحسابات الأخرى:

let n = 2;

n *= 3 + 5;

alert( n ); // 16  (right part evaluated first, same as n *= 8)

الزيادة / النقصان

<! – لا يمكن استخدامه – في العنوان ، لأن المحلل اللغوي المدمج يحوله إلى “شرطة طويلة” – →

تعد زيادة أو إنقاص عدد بمقدار واحد من بين العمليات العددية الأكثر شيوعًا.

لذلك ، هناك عوامل خاصة لذلك:

  • ** زيادة ** ++ يزيد المتغير بمقدار 1:

    let counter = 2;
    counter++;        //يعمل مثل counter = counter + 1 ولكنه أقصر
    alert( counter ); // 3
  • Decrement -- decreases a variable by 1:

    let counter = 2;
    counter--;        // يعمل مثل counter = counter - 1 ولكنه أقصر
    alert( counter ); // 1
لا يمكن تطبيق الزيادة / التناقص إلا على المتغيرات. محاولة استخدامه على قيمة مثل `5 ++` سيعطي خطأ.

يمكن وضع عوامل التشغيل ++ و-- قبل أو بعد المتغير.

  • عندما يسير المشغل بعد المتغير ، يكون في “نموذج postfix”: counter ++.
  • “شكل البادئة” هو عندما يذهب عامل التشغيل قبل المتغير: عداد ++.

كلتا العبارتين تفعلان نفس الشيء: زيادة “العداد” بمقدار “1”.

هل هناك فرق؟ نعم ، ولكن لا يمكننا رؤيتها إلا إذا استخدمنا القيمة المرتجعة لـ “++ / -”.

دعونا نوضح. كما نعلم ، ترجع كل عوامل التشغيل قيمة. زيادة / إنقاص ليست استثناء. يُرجع نموذج البادئة القيمة الجديدة بينما يُرجع نموذج postfix القيمة القديمة (قبل الزيادة / التناقص).

لمعرفة الفرق ، إليك مثال:

let counter = 1;
let a = ++counter; // (*)

alert(a); // 2

في السطر (*) ، * البادئة * من ++ counter تزيدالعداد وتعيد القيمة الجديدة 2. لذا ، يُظهر “التنبيه” “2”.

الآن ، دعنا نستخدم شكل البادئة postfix:

let counter = 1;
let a = counter++; // (*) changed ++counter to counter++

alert(a); // 1

في السطر (*) ، فإن البادئة من counter ++ يزيد أيضًا من “العداد” ولكنه يُرجع قيمة * القديمة * (قبل الزيادة). لذا ، يُظهر “التنبيه” “1”.

باختصار:

  • إذا لم يتم استخدام نتيجة الزيادة / النقصان ، فلا فرق في الشكل المستخدم:

    let counter = 0;
    counter++;
    ++counter;
    alert( counter ); // 2, the lines above did the same
  • إذا أردنا زيادة القيمة واستخدام نتيجة عامل التشغيل على الفور ، فنحن بحاجة إلى نموذج البادئة:

    let counter = 0;
    alert( ++counter ); // 1
  • إذا كنا نرغب في زيادة قيمة ولكننا نستخدم قيمتها السابقة ، فنحن بحاجة إلى شكل postfix:

    let counter = 0;
    alert( counter++ ); // 0
يمكن استخدام عوامل التشغيل `++ / -` داخل التعبيرات أيضًا. أسبقيتها أعلى من معظم العمليات الحسابية الأخرى.

على سبيل المثال:

```js run
let counter = 1;
alert( 2 * ++counter ); // 4
```

بالمقارنة مع:

```js run
let counter = 1;
alert( 2 * counter++ ); // 2, because counter++ returns the "old" value
```

على الرغم من أنه بخير من الناحية الفنية ، فإن مثل هذا التدوين يجعل التعليمات البرمجية أقل قابلية للقراءة. سطر واحد يقوم بأشياء متعددة - ليس جيدًا.

أثناء قراءة الرمز ، يمكن أن يفقد مسح العين "العمودي" السريع شيئًا مثل `` عداد ++ '' ولن يكون من الواضح أن المتغير زاد.

ننصح بأسلوب "سطر واحد - عمل واحد":

```js run
let counter = 1;
alert( 2 * counter );
counter++;
```

عوامل تشغيل Bitwise أحادية المعامل

يعامل عاملو Bitwise الوسيطات كأرقام صحيحة 32 بت ويعملون على مستوى تمثيلهم الثنائي.

هذه العوامل ليست خاصة بـ JavaScript. يتم دعمها في معظم لغات البرمجة.

قائمة عوامل التشغيل:

  • AND ( & )
  • OR ( | )
  • XOR ( ^ )
  • NOT ( ~ )
  • LEFT SHIFT ( << )
  • RIGHT SHIFT ( >> )
  • ZERO-FILL RIGHT SHIFT ( >>> )

نادرًا ما يتم استخدام عوامل التشغيل هذه ، عندما نحتاج إلى التلاعب بالأرقام على أدنى مستوى (أحادي البتات). لن نحتاج إلى هؤلاء المشغلين في أي وقت قريب ، لأن تطوير الويب لا يستخدمهم كثيرًا ، ولكن في بعض المجالات الخاصة ، مثل التشفير ، فهي مفيدة. يمكنك قراءة مقالة [عوامل تشغيل Bitwise] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) مقالة حول MDN عند الحاجة.

الفاصلة

عامل الفاصلة ، هو أحد أندر العمليات وأكثرها غرابة. في بعض الأحيان ، يتم استخدامه لكتابة رمز أقصر ، لذلك نحتاج إلى معرفته من أجل فهم ما يحدث.

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

فمثلا:

let a = (1 + 2, 3 + 4);

alert( a ); // 7 (the result of 3 + 4)

هنا ، يتم تقييم التعبير الأول 1 + 2 ويتم التخلص من نتائجه. ثم يتم تقييم 3 + 4 وإرجاعها كنتيجة.

يرجى ملاحظة أن عامل الفاصلة له أسبقية منخفضة جدًا ، أقل من `=` ، لذا فإن الأقواس مهمة في المثال أعلاه.

بدونها: `a = 1 + 2 ، 3 + 4` يقيم` + `أولاً ، يلخص الأرقام في` a = 3 ، 7` ، ثم عامل التعيين `=` يخصص `a = 3` ، والباقي هو تجاهلها. إنه مثل `(أ = 1 + 2) ، 3 + 4`.

لماذا نحتاج إلى عامل يعمل على التخلص من كل شيء باستثناء التعبير الأخير؟

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

فمثلا:

// ثلات عمليات حسابية في سطر واحد
for (a = 1, b = 3, c = a * b; a < 10; a++) {
 ...
}

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

مهمه

ما هي القيم النهائية لجميع المتغيرات a وb وc وd بعد الكود أدناه؟

let a = 1, b = 1;

let c = ++a; // ?
let d = b++; // ?

الإجابة هي:

  • a = 2
  • b = 2
  • c = 2
  • d = 1
let a = 1, b = 1;

alert( ++a ); // 2, prefix form returns the new value
alert( b++ ); // 1, postfix form returns the old value

alert( a ); // 2, incremented once
alert( b ); // 2, incremented once

ما هي قيم a وx بعد الكود أدناه؟

let a = 2;

let x = 1 + (a *= 2);

الإجابة هي:

  • a = 4 (multiplied by 2)
  • x = 5 (calculated as 1 + 4)

ما هي نتائج هذه التعبيرات؟

"" + 1 + 0
"" - 1 + 0
true + false
6 / "3"
"2" * "3"
4 + 5 + "px"
"$" + 4 + 5
"4" - 2
"4px" - 2
7 / 0
"  -9  " + 5
"  -9  " - 5
null + 1
undefined + 1
" \t \n" - 2

فكر جيدًا ، واكتب ثم قارن مع الإجابة.

"" + 1 + 0 = "10" // (1)
"" - 1 + 0 = -1 // (2)
true + false = 1
6 / "3" = 2
"2" * "3" = 6
4 + 5 + "px" = "9px"
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
7 / 0 = Infinity
"  -9  " + 5 = "  -9  5" // (3)
"  -9  " - 5 = -14 // (4)
null + 1 = 1 // (5)
undefined + 1 = NaN // (6)
" \t \n" - 2 = -2 // (7)
  1. الإضافة بسلسلة “” + 1تحول1إلى سلسلة: “” + 1 = “1” ، وبعد ذلك لدينا" 1 "+ 0 ، يتم تطبيق نفس القاعدة.
  2. يعمل الطرح - (مثل معظم عمليات الرياضيات) مع الأرقام فقط ، فهو يحول سلسلة فارغة" “” إلى “0”.
  3. الإضافة بسلسلة تلحق الرقم 5 بالسلسلة.
  4. يتحول الطرح دائمًا إلى أرقام ، لذلك يجعل “-9” رقمًا -9 (تجاهل المسافات حوله).
  5. يصبح “null” “0” بعد التحويل الرقمي.
  6. يصبح “غير معرّف” “NaN” بعد التحويل الرقمي.
  7. يتم قطع أحرف المسافة من بداية السلسلة ونهايتها عند تحويل سلسلة إلى رقم. تتكون السلسلة بأكملها هنا من أحرف مسافة ، مثل \ t و\ n ومسافة “عادية” بينهما. لذا ، على غرار السلسلة الفارغة ، تصبح 0.

إليك رمز يطلب من المستخدم رقمين ويظهر مجموعهم.

يعمل بشكل غير صحيح. الإخراج في المثال أدناه هو 12 (لقيم المطالبة الافتراضية).

لماذا ا؟ اصلحه. يجب أن تكون النتيجة 3.

let a = prompt("First number?", 1);
let b = prompt("Second number?", 2);

alert(a + b); // 12

السبب هو أن موجه إرجاع إدخال المستخدم كسلسلة.

حتى المتغيرات لها قيم “1” و “2” على التوالي.

let a = "1"; // prompt("First number?", 1);
let b = "2"; // prompt("Second number?", 2);

alert(a + b); // 12

ما يجب علينا فعله هو تحويل السلاسل إلى أرقام قبل +. على سبيل المثال ، استخدام Number () أو إلحاقها بـ +.

على سبيل المثال ، قبل “prompt” مباشرةً:

let a = +prompt("First number?", 1);
let b = +prompt("Second number?", 2);

alert(a + b); // 3

أو في alert:

let a = prompt("First number?", 1);
let b = prompt("Second number?", 2);

alert(+a + +b); // 3

استخدام كل من + أحادي وثنائي `في آخر كود. يبدو مضحك ، أليس كذلك؟

خريطة الدورة التعليمية

التعليقات

إقرأ هذا قبل أن تضع تعليقًا…
  • إذا كان لديك اقتراحات أو تريد تحسينًا - من فضلك من فضلك إفتح موضوعًا فى جيتهاب أو شارك بنفسك بدلًا من التعليقات.
  • إذا لم تستطع أن تفهم شيئّا فى المقال - وضّح ماهو.
  • إذا كنت تريد عرض كود استخدم عنصر <code> ، وللكثير من السطور استخدم <pre>، ولأكثر من 10 سطور استخدم (plnkr, JSBin, codepen…)