نحن نعرف العديد من المشغلين من المدرسة. وهي أشياء مثل الجمع +
والضرب *
والطرح -
وما إلى ذلك.
في هذا الفصل، سنبدأ بالعوامل البسيطة، ثم نركز على الجوانب الخاصة بجافا سكريبت، والتي لا تغطيها الرياضيات المدرسية.
قبل أن ننتقل، دعونا نفهم بعض المصطلحات الشائعة.
المعامل – هو ما يتم تطبيق عوامل التشغيل عليه. على سبيل المثال، في ضرب 5 * 2
هناك معاملان: المعامل الأيسر هو 5
والمعامل الأيمن هو 2
. في بعض الأحيان، يطلق الناس على هذه "الحجج" بدلاً من "المعاملات".
يكون العامل أحاديًا إذا كان له مُعامل واحد. على سبيل المثال، النفي الأحادي -
يعكس إشارة الرقم:
دع س = 1؛ س = -س؛ تنبيه(x); // -1، تم تطبيق النفي الأحادي
يكون العامل ثنائيًا إذا كان له معاملان. نفس الطرح موجود في الشكل الثنائي أيضًا:
دع س = 1، ص = 3؛ تنبيه (ص - س)؛ // 2، ثنائي ناقص يطرح القيم
رسميًا، في الأمثلة أعلاه لدينا عاملين مختلفين يشتركان في نفس الرمز: عامل النفي، وهو عامل أحادي يعكس الإشارة، وعامل الطرح، وهو عامل ثنائي يطرح رقمًا من رقم آخر.
يتم دعم العمليات الحسابية التالية:
إضافة +
,
الطرح -
,
الضرب *
,
قسم /
،
%
المتبقية ,
الأس **
.
الأربعة الأولى واضحة ومباشرة، في حين أن %
و **
بحاجة إلى بضع كلمات عنها.
العامل المتبقي %
، على الرغم من مظهره، لا يرتبط بالنسب المئوية.
نتيجة a % b
هي باقي القسمة الصحيحة لـ a
على b
.
على سبيل المثال:
تنبيه( 5% 2 ); // 1، باقي 5 مقسومًا على 2 تنبيه( 8% 3 ); // 2، باقي 8 مقسومًا على 3 تنبيه( 8% 4 ); // 0، باقي 8 مقسومًا على 4
عامل الأس a ** b
يرفع a
للأس b
.
في الرياضيات المدرسية، نكتب ذلك بالشكل b .
على سبيل المثال:
تنبيه( 2 ** 2 ); // 2² = 4 تنبيه( 2 ** 3 ); // 2³ = 8 تنبيه( 2 ** 4 ); // 2⁴ = 16
كما هو الحال في الرياضيات، يتم تعريف عامل الأسي للأعداد غير الصحيحة أيضًا.
على سبيل المثال، الجذر التربيعي هو الأس بمقدار ½:
تنبيه( 4 ** (1/2) ); // 2 (أس 1/2 هو نفس الجذر التربيعي) تنبيه( 8 ** (1/3) ); // 2 (أس 1/3 هو نفس الجذر التكعيبي)
دعونا نتعرف على ميزات مشغلي JavaScript التي تتجاوز العمليات الحسابية المدرسية.
عادة، عامل الجمع +
مجموع الأرقام.
ولكن، إذا تم تطبيق الثنائي +
على السلاسل، فإنه يدمجها (يسلسلها):
دعونا s = "بلدي" + "سلسلة"؛ التنبيه (التنبيهات)؛ // mystring
لاحظ أنه إذا كان أي من المعاملات عبارة عن سلسلة، فسيتم تحويل الآخر إلى سلسلة أيضًا.
على سبيل المثال:
تنبيه('1'+2); // "12" تنبيه(2 + '1' ); // "21"
انظر، لا يهم ما إذا كان المعامل الأول عبارة عن سلسلة أو المعامل الثاني.
إليك مثال أكثر تعقيدًا:
تنبيه(2 + 2 + '1' ); // "41" وليس "221"
هنا، يعمل المشغلون واحدًا تلو الآخر. الأول +
يجمع رقمين، لذا يُرجع 4
، ثم يضيف التالي +
السلسلة 1
إليه، لذا فهو مثل 4 + '1' = '41'
.
تنبيه('1' + 2 + 2); // "122" وليس "14"
هنا، المعامل الأول عبارة عن سلسلة، ويعامل المترجم المعاملين الآخرين كسلاسل أيضًا. يتم ربط 2
بـ '1'
، لذا فهو مثل '1' + 2 = "12"
و "12" + 2 = "122"
.
الثنائي +
هو العامل الوحيد الذي يدعم السلاسل بهذه الطريقة. تعمل العوامل الحسابية الأخرى فقط مع الأرقام وتقوم دائمًا بتحويل معاملاتها إلى أرقام.
وإليك العرض التوضيحي لعملية الطرح والقسمة:
تنبيه(6 - '2' ); // 4، يحول "2" إلى رقم تنبيه('6' / '2' ); // 3، يحول كلا المعاملين إلى أرقام
علامة الجمع +
موجودة في شكلين: الشكل الثنائي الذي استخدمناه أعلاه والشكل الأحادي.
إن علامة الجمع الأحادية، أو بعبارة أخرى، عامل زائد +
المطبق على قيمة واحدة، لا تفعل أي شيء للأرقام. ولكن إذا لم يكن المعامل رقمًا، فإن علامة الجمع الأحادية تحوله إلى رقم.
على سبيل المثال:
// لا يوجد تأثير على الأرقام دع س = 1؛ تنبيه(+x); // 1 دع ص = -2؛ تنبيه(+y); // -2 // تحويل غير الأرقام تنبيه(+صحيح); // 1 تنبيه(+""); // 0
إنه في الواقع يفعل نفس الشيء مثل Number(...)
ولكنه أقصر.
تنشأ الحاجة إلى تحويل السلاسل إلى أرقام في كثير من الأحيان. على سبيل المثال، إذا كنا نحصل على قيم من حقول نموذج HTML، فهي عادة ما تكون سلاسل. ماذا لو أردنا جمعهم؟
ستضيفها علامة الجمع الثنائية كسلاسل:
دع التفاح = "2"؛ دع البرتقال = "3"؛ تنبيه (تفاح + برتقال) ؛ // "23"، الجمع الثنائي يسلسل السلاسل
إذا أردنا التعامل معها كأرقام، نحتاج إلى تحويلها ثم جمعها:
دع التفاح = "2"؛ دع البرتقال = "3"؛ // تم تحويل كلا القيمتين إلى أرقام قبل علامة الجمع الثنائية تنبيه( +apples + +oranges ); // 5 // البديل الأطول // تنبيه( الرقم(التفاح) + الرقم(البرتقال)); // 5
من وجهة نظر عالم الرياضيات، قد تبدو وفرة الإيجابيات غريبة. لكن من وجهة نظر المبرمج، لا يوجد شيء خاص: يتم تطبيق علامات الجمع الأحادية أولاً، حيث تقوم بتحويل السلاسل إلى أرقام، ثم تقوم علامة الجمع الثنائية بجمعها.
لماذا يتم تطبيق الإيجابيات الأحادية على القيم قبل القيم الثنائية؟ وكما سنرى، هذا بسبب أسبقيتهم الأعلى .
إذا كان التعبير يحتوي على أكثر من عامل تشغيل واحد، فسيتم تحديد ترتيب التنفيذ حسب أسبقيتهم ، أو بمعنى آخر، ترتيب الأولوية الافتراضي لعوامل التشغيل.
نعلم جميعًا من المدرسة أن الضرب في العبارة 1 + 2 * 2
يجب أن يحسب قبل عملية الجمع. هذا هو بالضبط شيء الأسبقية. يقال أن الضرب له أسبقية أعلى من الجمع.
تتجاوز الأقواس أي أسبقية، لذلك إذا لم نكن راضين عن الترتيب الافتراضي، فيمكننا استخدامها لتغييره. على سبيل المثال، اكتب (1 + 2) * 2
.
هناك العديد من العوامل في JavaScript. كل عامل لديه رقم الأسبقية المقابل. الشخص ذو العدد الأكبر ينفذ أولاً. إذا كانت الأسبقية هي نفسها، يكون ترتيب التنفيذ من اليسار إلى اليمين.
فيما يلي مقتطف من جدول الأسبقية (لا تحتاج إلى تذكر ذلك، ولكن لاحظ أن العوامل الأحادية أعلى من العوامل الثنائية المقابلة):
أسبقية | اسم | لافتة |
---|---|---|
… | … | … |
14 | الأحادي زائد | + |
14 | النفي الأحادي | - |
13 | الأسي | ** |
12 | الضرب | * |
12 | قسم | / |
11 | إضافة | + |
11 | الطرح | - |
… | … | … |
2 | تكليف | = |
… | … | … |
كما نرى، فإن "الإضافة الأحادية" لها أولوية 14
وهي أعلى من 11
"الإضافة" (الإضافة الثنائية). لهذا السبب، في التعبير "+apples + +oranges"
تعمل علامات الجمع الأحادية قبل عملية الجمع.
دعونا نلاحظ أن المهمة =
هي أيضًا عامل تشغيل. وهي مدرجة في جدول الأسبقية بأولوية منخفضة للغاية وهي 2
.
لهذا السبب، عندما نقوم بتعيين متغير، مثل x = 2 * 2 + 1
، تتم الحسابات أولاً ثم يتم تقييم =
، وتخزين النتيجة في x
.
دع س = 2 * 2 + 1؛ تنبيه(x); // 5
حقيقة كون =
عامل، وليس بناء لغة "سحرية" لها آثار مثيرة للاهتمام.
تقوم جميع عوامل التشغيل في JavaScript بإرجاع قيمة. هذا واضح بالنسبة +
و -
، ولكنه صحيح أيضًا بالنسبة =
.
الاستدعاء x = value
يكتب value
في x
ثم يعيدها .
فيما يلي عرض توضيحي يستخدم مهمة كجزء من تعبير أكثر تعقيدًا:
دع = 1؛ دع ب = 2؛ دع ج = 3 - (أ = ب + 1)؛ تنبيه (أ)؛ // 3 تنبيه (ج)؛ // 0
في المثال أعلاه، نتيجة التعبير (a = b + 1)
هي القيمة التي تم تعيينها a
(أي 3
). ثم يتم استخدامه لمزيد من التقييمات.
رمز مضحك، أليس كذلك؟ يجب أن نفهم كيف تعمل، لأننا أحيانًا نراها في مكتبات JavaScript.
على الرغم من ذلك، من فضلك لا تكتب الكود بهذه الطريقة. من المؤكد أن مثل هذه الحيل لا تجعل التعليمات البرمجية أكثر وضوحًا أو قابلية للقراءة.
ميزة أخرى مثيرة للاهتمام هي القدرة على تسلسل المهام:
دع أ، ب، ج؛ أ = ب = ج = 2 + 2؛ تنبيه (أ)؛ // 4 تنبيه (ب) ؛ // 4 تنبيه (ج)؛ // 4
يتم تقييم المهام المتسلسلة من اليمين إلى اليسار. أولاً، يتم تقييم التعبير الموجود في أقصى اليمين 2 + 2
ثم يتم تعيينه للمتغيرات الموجودة على اليسار: c
و b
و a
. وفي النهاية، تشترك جميع المتغيرات في قيمة واحدة.
مرة أخرى، لأغراض سهولة القراءة، من الأفضل تقسيم هذه التعليمات البرمجية إلى بضعة أسطر:
ج = 2 + 2؛ ب = ج؛ أ = ج؛
وهذا أسهل في القراءة، خاصة عند مسح الرمز ضوئيًا بسرعة.
غالبًا ما نحتاج إلى تطبيق عامل تشغيل على متغير وتخزين النتيجة الجديدة في نفس المتغير.
على سبيل المثال:
دع ن = 2؛ ن = ن + 5؛ ن = ن * 2؛
يمكن اختصار هذا الترميز باستخدام عاملي التشغيل +=
و *=
:
دع ن = 2؛ ن += 5; // الآن n = 7 (مثل n = n + 5) ن *= 2; // الآن n = 14 (مثل n = n * 2) تنبيه(ن); // 14
توجد عوامل تشغيل "تعديل وتعيين" قصيرة لجميع عوامل التشغيل الحسابية والبتية: /=
، -=
، وما إلى ذلك.
تتمتع هذه العوامل بنفس الأسبقية للتخصيص العادي، لذا فهي تعمل بعد معظم الحسابات الأخرى:
دع ن = 2؛ ن *= 3 + 5؛ // يتم تقييم الجزء الأيمن أولاً، مثل n *= 8 تنبيه(ن); // 16
تعد زيادة أو تقليل الرقم بمقدار واحد من أكثر العمليات العددية شيوعًا.
لذلك، هناك مشغلين خاصين لذلك:
الزيادة ++
تزيد المتغير بمقدار 1:
دع العداد = 2؛ عداد++; // يعمل بنفس طريقة عمل counter = counter + 1، ولكنه أقصر تنبيه (عداد)؛ // 3
إنقاص --
تقليل المتغير بمقدار 1:
دع العداد = 2؛ عداد--؛ // يعمل بنفس طريقة عمل العداد = العداد - 1، ولكنه أقصر تنبيه (عداد)؛ // 1
مهم:
لا يمكن تطبيق الزيادة/النقصان إلا على المتغيرات. محاولة استخدامه على قيمة مثل 5++
ستؤدي إلى حدوث خطأ.
يمكن وضع عوامل التشغيل ++
--
قبل المتغير أو بعده.
عندما يلاحق العامل المتغير، يكون ذلك في "نموذج postfix": counter++
.
"نموذج البادئة" هو عندما يذهب عامل التشغيل قبل المتغير: ++counter
.
كلتا العبارتين تفعلان الشيء نفسه: زيادة counter
بمقدار 1
.
هل هناك أي فرق؟ نعم، ولكن لا يمكننا رؤيتها إلا إذا استخدمنا القيمة التي تم إرجاعها ++/--
.
دعونا نوضح. كما نعلم، جميع عوامل التشغيل تقوم بإرجاع قيمة. الزيادة/النقصان ليست استثناء. يقوم نموذج البادئة بإرجاع القيمة الجديدة بينما يقوم نموذج postfix بإرجاع القيمة القديمة (قبل الزيادة/النقصان).
ولمعرفة الفرق إليك المثال:
دع العداد = 1؛ دع = ++ عداد؛ // (*) تنبيه (أ)؛ // 2
في السطر (*)
، تزيد صيغة البادئة ++counter
من counter
وترجع القيمة الجديدة، 2
. لذلك، يظهر alert
2
.
الآن، لنستخدم نموذج postfix:
دع العداد = 1؛ دع = عداد++؛ // (*) تم تغيير ++count إلى counter++ تنبيه (أ)؛ // 1
في السطر (*)
، يقوم نموذج postfix counter++
أيضًا بزيادة counter
ولكنه يُرجع القيمة القديمة (قبل الزيادة). لذلك، يظهر alert
1
.
لتلخيص:
إذا لم يتم استخدام نتيجة الزيادة/النقصان، فلا يوجد فرق في النموذج الذي سيتم استخدامه:
دع العداد = 0؛ عداد++; ++عداد; تنبيه (عداد)؛ // 2، السطر أعلاه فعل الشيء نفسه
إذا أردنا زيادة قيمة واستخدام نتيجة العامل على الفور، فسنحتاج إلى نموذج البادئة:
دع العداد = 0؛ تنبيه(++عداد); // 1
إذا أردنا زيادة قيمة ولكننا نستخدم قيمتها السابقة، فسنحتاج إلى نموذج postfix:
دع العداد = 0؛ تنبيه (عداد ++)؛ // 0
الزيادة/النقصان بين العوامل الأخرى
يمكن استخدام عوامل التشغيل ++/--
داخل التعبيرات أيضًا. أسبقيتها أعلى من معظم العمليات الحسابية الأخرى.
على سبيل المثال:
دع العداد = 1؛ تنبيه (2 * ++ عداد )؛ // 4
قارن مع:
دع العداد = 1؛ تنبيه (2 * عداد ++)؛ // 2، لأن العداد ++ يُرجع القيمة "القديمة".
على الرغم من أنه جيد من الناحية الفنية، إلا أن مثل هذا التدوين عادة ما يجعل التعليمات البرمجية أقل قابلية للقراءة. سطر واحد يفعل أشياء متعددة - ليس جيدًا.
أثناء قراءة التعليمات البرمجية، يمكن لمسح العين "العمودي" السريع أن يخطئ بسهولة شيئًا مثل counter++
ولن يكون من الواضح أن المتغير قد زاد.
ننصح بأسلوب "سطر واحد – إجراء واحد":
دع العداد = 1؛ تنبيه (2 * عداد)؛ عداد++;
يتعامل مشغلو Bitwise مع الوسيطات كأرقام صحيحة 32 بت ويعملون على مستوى تمثيلهم الثنائي.
عوامل التشغيل هذه ليست خاصة بجافا سكريبت. وهي مدعومة في معظم لغات البرمجة.
قائمة المشغلين:
و ( &
)
أو ( |
)
إكس أو آر ( ^
)
ليس ( ~
)
التحول الأيسر ( <<
)
التحول لليمين ( >>
)
صفر ملء التحول الأيمن ( >>>
)
نادرًا ما يتم استخدام عوامل التشغيل هذه، عندما نحتاج إلى التلاعب بالأرقام على المستوى الأدنى (مستوى البت). لن نحتاج إلى هذه العوامل في أي وقت قريب، نظرًا لأن تطوير الويب لا يستخدمها كثيرًا، ولكنها مفيدة في بعض المجالات الخاصة، مثل التشفير. يمكنك قراءة فصل Bitwise Operators على MDN عند الحاجة.
يعد عامل ,
واحدًا من أندر العوامل وأكثرها غرابة. في بعض الأحيان، يتم استخدامه لكتابة تعليمات برمجية أقصر، لذلك نحتاج إلى معرفتها لفهم ما يحدث.
يتيح لنا عامل الفاصلة تقييم العديد من التعبيرات وتقسيمها بفاصلة ,
يتم تقييم كل واحد منهم ولكن يتم إرجاع نتيجة الأخير فقط.
على سبيل المثال:
دع أ = (1 + 2، 3 + 4)؛ تنبيه (أ)؛ // 7 (نتيجة 3 + 4)
وهنا يتم تقييم التعبير الأول 1 + 2
ورمي نتيجته. ثم يتم تقييم 3 + 4
وإرجاعها بالنتيجة.
الفاصلة لها أسبقية منخفضة للغاية
يرجى ملاحظة أن عامل الفاصلة له أسبقية منخفضة جدًا، أقل من =
، لذا فإن الأقواس مهمة في المثال أعلاه.
بدونها: a = 1 + 2, 3 + 4
يتم تقييمه +
أولاً، وجمع الأرقام في a = 3, 7
، ثم يقوم عامل التعيين =
بتعيين a = 3
، ويتم تجاهل الباقي. مثل (a = 1 + 2), 3 + 4
.
لماذا نحتاج إلى عامل يتخلص من كل شيء باستثناء التعبير الأخير؟
في بعض الأحيان، يستخدمه الأشخاص في بنيات أكثر تعقيدًا لوضع عدة إجراءات في سطر واحد.
على سبيل المثال:
// ثلاث عمليات في سطر واحد لـ (أ = 1، ب = 3، ج = أ * ب؛ أ < 10؛ أ++) { ... }
تُستخدم مثل هذه الحيل في العديد من أطر عمل JavaScript. ولهذا السبب نذكرهم. لكنها عادةً لا تعمل على تحسين إمكانية قراءة التعليمات البرمجية، لذا يجب أن نفكر جيدًا قبل استخدامها.
الأهمية: 5
ما هي القيم النهائية لجميع المتغيرات a
و b
و c
و d
بعد الكود أدناه؟
دع أ = 1، ب = 1؛ دع ج = ++ا؛ // ؟ دع د = ب++؛ // ؟
الجواب هو:
a = 2
b = 2
c = 2
d = 1
دع أ = 1، ب = 1؛ تنبيه(++أ); // 2، نموذج البادئة يُرجع القيمة الجديدة تنبيه (ب++)؛ // 1، يُرجع نموذج postfix القيمة القديمة تنبيه (أ)؛ // 2، زيادة مرة واحدة تنبيه (ب) ؛ // 2، زيادة مرة واحدة
الأهمية: 3
ما هي قيم a
و x
بعد الكود أدناه؟
دع = 2؛ دع س = 1 + (أ *= 2)؛
الجواب هو:
a = 4
(مضروبة في 2)
x = 5
(محسوبة على أنها 1 + 4)
الأهمية: 5
ما هي نتائج هذه التعبيرات؟
""+1+0 "" - 1 + 0 صحيح + خطأ 6 / "3" "2" * "3" 4 + 5 + "بكسل" "$" + 4 + 5 "4" - 2 "4 بكسل" - 2 "-9" + 5 "-9"-5 خالية + 1 غير محدد +1 " t n" - 2
فكر جيدًا، واكتب ثم قارن مع الإجابة.
"" + 1 + 0 = "10" // (1) "" - 1 + 0 = -1 // (2) صحيح + خطأ = 1 6 / "3" = 2 "2" * "3" = 6 4 + 5 + "بكسل" = "9بكسل" "$" + 4 + 5 = "45 دولارًا" "4" - 2 = 2 "4 بكسل" - 2 = نان " -9 " + 5 = " -9 5" // (3) " -9 " - 5 = -14 // (4) فارغة + 1 = 1 // (5) غير محدد + 1 = NaN // (6) " t n" - 2 = -2 // (7)
الإضافة بسلسلة "" + 1
تحول 1
إلى سلسلة: "" + 1 = "1"
، ثم لدينا "1" + 0
، يتم تطبيق نفس القاعدة.
الطرح -
(مثل معظم العمليات الحسابية) يعمل فقط مع الأرقام، فهو يحول سلسلة فارغة ""
إلى 0
.
الإضافة بسلسلة تُلحق الرقم 5
بالسلسلة.
يتحول الطرح دائمًا إلى أرقام، لذا فهو يجعل " -9 "
رقمًا -9
(متجاهلاً المسافات المحيطة به).
يصبح null
0
بعد التحويل الرقمي.
undefined
يصبح NaN
بعد التحويل الرقمي.
يتم اقتطاع أحرف المسافة من بداية السلسلة ونهايتها عند تحويل سلسلة إلى رقم. تتكون السلسلة بأكملها هنا من أحرف مسافات، مثل t
و n
ومسافة "عادية" بينهما. لذلك، على غرار سلسلة فارغة، يصبح 0
.
الأهمية: 5
إليك رمز يطلب من المستخدم رقمين ويعرض مجموعهما.
إنه يعمل بشكل غير صحيح. الإخراج في المثال أدناه هو 12
(لقيم المطالبة الافتراضية).
لماذا؟ أصلحه. يجب أن تكون النتيجة 3
.
Let a = موجه("الرقم الأول؟", 1); Let b = موجه("الرقم الثاني؟", 2); تنبيه (أ + ب)؛ // 12
والسبب هو أن المطالبة تُرجع إدخال المستخدم كسلسلة.
لذا فإن المتغيرات لها قيم "1"
و "2"
على التوالي.
دع = "1"؛ // موجه ("الرقم الأول؟"، 1)؛ دع ب = "2"؛ // موجه ("الرقم الثاني؟"، 2)؛ تنبيه (أ + ب)؛ // 12
ما يجب علينا فعله هو تحويل السلاسل إلى أرقام قبل +
. على سبيل المثال، استخدام Number()
أو إضافتها مسبقًا بـ +
.
على سبيل المثال، مباشرة قبل prompt
:
Let a = +prompt("الرقم الأول؟", 1); Let b = +prompt("الرقم الثاني؟", 2); تنبيه (أ + ب)؛ // 3
أو في alert
:
Let a = موجه("الرقم الأول؟", 1); Let b = موجه("الرقم الثاني؟", 2); تنبيه(+أ++ب); // 3
استخدام كل من الأحادي والثنائي +
في أحدث التعليمات البرمجية. يبدو مضحكا، أليس كذلك؟