اگر بلوکهای سازندهٔ یک ساختمان را آجرها تشکیل میدهند، بلوکهای سازندهٔ زبانهایی همچون جاوااسکریپت نیز اجزایی تحت عنوان Operator ،Expression و Statement خواهند بود به طوری که با کمک این اجزاء میتوانیم مقادیر را دستکاری کرده و تغییر دهیم، عملیات ریاضیاتی انجام دهیم، دو یا چند مقدار را با هم مقایسه کنیم و خیلی از کارهای دیگر که در این آموزش تمرکز رو مفهوم اپراتور و کاربرد اپراتورها در زبان جاوااسکریپت است.
به هر تکه کدی که به یک مقدار منجر شود، Expression میگویند به طوری که این اصطلاح یا مقداری را به یک متغیر اختصاص میدهد یا آنکه خودش حاوی یک مقدار است. برای مثال، هر یک از خطوط زیر یک اِکسپرشن محسوب میشود:
1 + 1
a = 1;
اِکسپرشنها میتوانند همانند نمونههای بالا ساده و کوتاه باشند اما از طرفی دیگر برخی از آنها نیز میتوانند بسیار پیچیده و طولانی باشند (لازم به یادآوری است که به هر تکه از دیتا مثل 1 و یا a
که در اِکسپرشنهای فوق به کار برده شدهاند Operand به معنی «عملوند» گفته میشود.)
Statement به بلوکهای کدی در جاوااسکریپت گفته میشود که کار خاصی را انجام میدهند به طوری که مثلاً دستورات شرطی و یا حلقهها نمونههایی از اِستیتمنت هستند. همچنین توجه داشته باشیم که یک اِستیتمنت میتواند حاوی چندین اِکسپرشن باشد:
var x;
var y;
if (y >= 0) {
x = y;
} else {
x = -y;
}
بلوک کد فوق یک اِستیتمنت شرطی است که داخل آن از چندین اِکسپرشن استفاده شده است.
حال با این توضیحات، باید این نکته را یادآور شویم موتوری که باعث میشود اِکسپرشنها به کار بیفتند و کار خود را انجام دهند، Operator به معنی «عملگر» است به طوری که با انجام عملیات بر روی دیتای مختلف، نتایج و خروجیهای مختلفی تولید میکند (برای نمونه، علائم =
و +
در اِکسپرشنهای قبلی، اپراتور محسوب میشوند.) یک اِکسپرشن ساده میتواند شامل چند اپراتور شود:
var x = 100 + 50 * 3;
بسته به ترتیب عملیاتی که انجام میدهیم، خروجی نهایی میتواند یکی از این دو مورد باشد:
x = 450
x = 250
در اینجا میتوان ابتدا 50 را در 3 ضرب کرد سپس جوابش را با 100 جمع کرد یا اینکه میتوان ابتدا 100 را با 50 جمع کرده سپس حاصلجمع آنها را در عدد ۳ ضرب کرد اما اگر اینطور پیش برویم، هر بار با جوابی متفاوت روبهرو میشویم و از همین روی حتماً باید روشی برای تعیین جواب استاندارد و صحیح وجود داشته باشد.
در واقع، جواب صحیح این معادله برابر با 250 است اما پرسش اینجا است که «از کجا باید این را فهمید؟» در زبان جاوااسکریپت برخی اپراتورها نسبت به سایرین اولویت دارند و باید ابتدا محاسبات آنها را انجام داد. در حقیقت، اولویت ضرب و تقسیم بیش از جمع و تفریق است اما در عین حال سؤال دیگری که ممکن است پیش آید این است که «اگر بخواهیم از این اصول پیروی نکنیم چهطور؟» که برای پاسخ به این پرسش مثال زیر را مد نظر قرار میدهیم:
var x = (100 + 50) * 3;
همانطور که در مثال فوق میبینیم، با قرار دادن دستورات مد نظر داخل پرانتز میتوانیم اولویت آنها را بالاتر ببریم که در این صورت خروجی اِکسپرشن بالا برابر با عدد ۴۵۰ خواهد بود. زمانهایی هم در کدنویسی برایمان پیش خواهد آمد که با اپراتورهایی مواجه میشویم که از اولویت یکسانی برخوردارند که برای مثال اِکسپرشن زیر را میتوان در نظر گرفت:
var x = 100 + 50 - 3;
در چنین مواقعی، از آنجا که اولویت علائم +
و -
برابر است، از همین روی محاسبه از سمت چپ به راست صورت میگیرد؛ به عبارت دیگر، در مثال بالا ابتدا عدد ۱۰۰ با ۵۰ جمع شده سپس عدد ۳ از حاصلجمع آنها کسر میشود که در نتیجه عدد 147 به دست خواهد آمد.
آشنایی با اولویت اپراتورها در جاوااسکریپت
اپراتورها از نظر اولویت و تقدم به گروههای متفاوتی دستهبندی میشوند که هر کدام از این گروهها دارای یک شماره از 0 تا 19 است که این شماره نشاندهندهٔ اولویت آن اپراتور است و هرچه شماره کوچکتر باشد، اپراتور مد نظر از اولویت بالاتری برخوردار است به طوری که اپراتوری با اولویت 0 از تمامی دیگر اپراتورها در یک اِکسپرشن اولویت بالاتری دارد و مفسر این زبان ابتدا به سراغ آن خواهد رفت. به همین روال، اپراتوری با شمارهٔ اولویت 19 در آخرین رده قرار دارد.
برای درک بهتر این موضوع، در ادامه لیستی از پرکاربردترین اپراتورها در زبان جاوااسکریپت را در ادامه مد نظر قرار خواهیم داد:
اپراتور | کاربرد | اولویت | جهت تخصیص دهی | مثال |
( ) | گروهبندی اِکسپرشنها | 0 | -- | (1 + 3) |
. | دسترسی به پراپرتی | 1 | چپ به راست | myCar.color |
[ ] | دسترسی به اندیسهای یک آرایه | 1 | چپ به راست | [thingsToDo[4 |
++ | افزایش پسوندی | 3 | -- | ++number |
-- | کاهش پسوندی | 3 | -- | --number |
! | NOT منطقی | 4 | راست به چپ | value! |
~ | NOT بیتی (در مدارهای منطقی) | 4 | راست به چپ | value~ |
- | منفیسازی | 4 | راست به چپ | aNumber- |
++ | افزایش پیشوندی | 4 | راست به چپ | aNumber++ |
-- | کاهش پیشوندی | 4 | راست به چپ | aNumber-- |
typeof | مشخصکنندهٔ نوع آبجکت | ۴ | راست به چپ | typeof myVar |
void | دستور دادن به مرورگر برای انجام ندادن هیچ کاری | 4 | راست به چپ | (void(0 |
delete | حذف | 4 | راست به چپ | delete object.property |
* | ضرب | 5 | چپ به راست | a = 3 * 7 |
/ | تقسیم | 5 | چپ به راست | a = 3 / 7 |
% | باقیمانده | 5 | چپ به راست | a = 7 % 3 |
+ | جمع | 6 | چپ به راست | a = 7 + 3 |
- | تفریق | 6 | چپ به راست | a = 3 – 7 |
>> | شیفت بیتی به چپ | 7 | چپ به راست | a = 3 << 7 |
<< | شیفت بیتی به راست | 7 | چپ به راست | a = 3 >> 7 |
<<< | شیفت بیتی به راست (با فِلگ 0) | 7 | چپ به راست | a = 3 >>> 7 |
> | کوچکتر از | 8 | چپ به راست | a < b |
=> | کوچکتر یا مساوی با | 8 | چپ به راست | a <= b |
< | بزرگتر از | 8 | چپ به راست | a > b |
=< | بزرگتر یا مساوی با | 8 | چپ به راست | a >= b |
in | بخشی از | 8 | چپ به راست | value in values |
== | برابری | 9 | چپ به راست | "3" == 3 |
=! | نابرابری | 9 | چپ به راست | "3" =! 3 |
=== | برابری مطلق | 9 | چپ به راست | "3" === 3 |
==! | نابرابری مطلق | 9 | چپ به راست | "3" ==! 3 |
& | AND بیتی | 10 | چپ به راست | r = a & b |
^ | XOR بیتی | 11 | چپ به راست | r = a ^ b |
| | OR بیتی | 12 | چپ به راست | r = a | b |
&& | AND منطقی | 13 | چپ به راست | a && b |
|| | OR منطقی | 14 | چپ به راست | a || b |
: ? | ساختار شرطی | 15 | راست به چپ | a ? 3 : 7 |
= | مقداردهی | 16 | راست به چپ | a = 3 |
=+ | مقداردهی | 16 | راست به چپ | a += 3 |
=- | مقداردهی | 16 | راست به چپ | a -= 3 |
=* | مقداردهی | 16 | راست به چپ | a *= 3 |
=/ | مقداردهی | 16 | راست به چپ | a /= 3 |
=% | مقداردهی | 16 | راست به چپ | a %= 3 |
=>> | مقداردهی | 16 | راست به چپ | a <<= 3 |
=<< | مقداردهی | 16 | راست به چپ | a >>= 3 |
=<<< | مقداردهی | 16 | راست به چپ | a >>>= 3 |
=& | مقداردهی | 16 | راست به چپ | a &= 3 |
=^ | مقداردهی | 16 | راست به چپ | a ^= 3 |
=| | مقداردهی | 16 | راست به چپ | a |= 3 |
, | کاما (ترتیب) | 18 | چپ به راست | a+b, c+d |
اگر یک اِکسپرشن دارای چند اپراتور با اولویتی یکسان بود، آن وقت «جهتِ تخصیصدهی» آن اپراتورها مد نظر قرار می گیرد و جاوااسکریپت با توجه به آن، ترتیب اجرای عملیات را تشخیص میدهد که در اینجا «جهتِ تخصیصدهی» بدین معنا است که اپراتورها از کدام طرف باید اجرا شده یا آنکه مورد ارزیابی قرار بگیرند. به عنوان مثال، ++
میتواند مقدار یک متغیر را به صورت پسوندی یک واحد افزایش دهد:
var num = 1;
var y = num++;
console.log(num, y); //returns 2 , 1
در اینجا دو متغیر num
و y
تعریف کردهایم و در ابتدا مقدار num
برابر 1 است و پس از آن متغیر y
را بر اساس ++num
تعریف کردهایم. در واقع، در اینجا جاوااسکریپت ابتدا y
را برابر num
که مقدارش برابر 1 است قرار میدهد سپس به اپراتور ++
میرسد و مقدار num
را یک واحد افزایش میدهد که بدین ترتیب وقتی نتیجه را مشاهده میکنیم، y
برابر مقدار ۱ است و خودِ num
یک واحد افزایش یافته است و برابر با 2 شده است (از آن جهت به اپراتور ++
پسوندی گفته میشود که در ابتدا عملیات مد نظر انجام میشود سپس این اپراتور مقدار متغیری که به آن متصل شده را یک واحد افزایش میدهد و لازم به یادآوری است که محل قرار گیری این اپراتور بعد از نام متغیر است.)
اپراتور --
نیز همانند اپراتور بالا عمل میکند اما با این تفاوت که به جای افزایش، یک واحد از مقدار متغیر کم میکند:
var num = 1;
var y = num--;
console.log(num, y); //returns 0 , 1
همانطور که میبینیم، در اینجا نیز ابتدا مقدار y
برابر num
قرار میگیرد سپس یک واحد از num
کم میشود و بدین ترتیب در آخر num
برابر با 0 و y
برابر با 1 خواهد بود.
اپراتور !
همواره خروجی true
یا false
(یا به عبارتی صفر یا یک) خواهد داشت و خلاف عبارتی که بر روی آن اعمال میشود را بیان میکند. به عنوان مثال داریم:
var num = 0;
var y = 1;
!num; //returns true
!y; //returns false
متغیر عددی num
دارای مقدار 0 است که در منطق جاوااسکریپت برابر false
است. بدین ترتیب، زمانی که با استفاده از اپراتور !
خلاف آن را میخواهیم، عبارت true
را نمایش میدهد. از طرفی، متغیر y
دارای مقدار 1 است که در منطق جاوااسکریپت برابر true
است و اگر بخواهیم خلاف آن را نمایش دهیم، باید علامت !
را قبل از آن تایپ کنیم که در نهایت خروجی false
ریترن خواهد شد.
همواره این نکته را مد نظر داشته باشیم که در زبان جاوااسکریپت عباراتی که در نهایت معادل با null ،0 ،NaN، " " یا undefined باشند از لحاظ منطقی برابر false
در نظر گرفته میشوند. بدین ترتیب اگر از اپراتور !
بر روی این عبارات استفاده کنیم، همواره جواب true
خواهد بود (اگر این اپراتور بر روی هر عبارت دیگری به جز عبارات فوقالذکر استفاده شود، خروجی آن همیشه false
خواهد بود.)
اپراتورهای بیتی، با عبارات خود مانند مقادیر 32 بیتی برخورد میکنند. هر عدد در منطق 32 بیتی ترکیبی از 32 عدد 0 یا 1 است که در کنار هم یک عدد را تشکیل میدهند. با آنکه اپراتورهای بیتی با منطق 32 بیتی عملیات خود را انجام میدهند، اما خروجی آنها به صورت اعداد معمولی در مبنای 10 نمایش داده میشود. برای مثال، عدد 9 در منطق 32 بیتی به شکل زیر خواهد بود که در صورت استفاده از ~
نشان داده شده است:
9 (base 10) = 00000000000000000000000000001001 (base 2)
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
عمل NOT در منطق بیتی بدین ترتیب عمل میکند که تمامی صفرها را به یک تبدیل میکند و تمامی یکها را نیز به صفر و همانطور که گفته شد، خروجی اپراتورهای بیتی همواره اعداد استاندارد در مبنای 10 است و به همین دلیل زمانی که عبارت 9~
را در پنجرهٔ کنسول جاوااسکریپت تایپ کنید، عبارت 10- را به شما نمایش خواهد داد. به طور کلی، ~
هر عدد در جاوااسکریپت، منفی یک عدد بیشتر از آن را به عنوان خروجی خواهد داد:
~x = - (x + 1)
اپراتور -
میتواند عملوند جلوی خود را قرینه سازد. به طور مثال داریم:
var num = 2;
var y = -6;
-num; //returns -2
-y //returns 6
هر یک از متغیرهای بالا دارای مقدار مثبت یا منفی بودهاند که پس از قرینهسازی، دقیقاً مقدار مخالف آنها به عنوان خروجی نمایش داده شده است.
اپراتور ++
یا به عبارتی «افزایش پیشوندی» عملکردی مشابه با «افزایش پسوندی» دارد که پیش از این معرفی شد بدان معنا که میتواند یک واحد به متغیر خود بیفزاید اما در عین حال تفاوتهایی نیز بین این دو اپراتور وجود دارد:
var num = 1;
var y = ++num;
console.log(num, y); //returns 2 , 2
در اسکریپت فوق، ابتدا متغیر num
با مقدار اولیهٔ 1 تعریف شده سپس مفسر جاوااسکریپت به سراغ خط دوم میرود که در آن متغیر y
ساخته میشود و زمانی که جاوااسکریپت میخواهد به y
مقداردهی کند، با اپراتور ++
مواجه میشود که قبل از نام متغیر قرار گرفته است (بر خلاف اپراتور پسوندی که پس از نام متغیر قرار میگرفت) و از همین روی ابتدا این اپراتور را بر روی متغیری که به آن متصل شده اِعمال میکند سپس جواب نهایی را به عنوان مقدار y
در نظر میگیرد و بدین ترتیب یک واحد به num
افزوده میشود و سپس نتیجهٔ آن یعنی 2 به متغیر y
اختصاص داده میشود.
اپراتور --
یا به عبارتی «کاهش پیشوندی» همانند اپراتور «افزایش پیشوندی» عمل میکند اما قبل از هر کاری یک واحد از عملوند خود میکاهد:
var num = 1;
var y = --num;
console.log(num , y); //returns 0 , 0
اپراتور typeof
همواره نوع عملوند جلوی خود را در قالب یک استرینگ نمایش میدهد. در مثالهای زیر سعی کردهایم انواع مختلفی از آبجکتهای جاوااسکریپت را به عنوان پارامتر ورودی typeof
در نظر گرفته و خروجی آنها را نیز به صورت کامنت مشخص سازیم:
// Numbers
typeof (37) //returns "number"
typeof (3.14) //returns "number"
typeof (Math.LN2) //returns "number"
typeof (NaN) //returns "number"
//Strings
typeof ("") //returns "string"
typeof ("bla") //returns "string"
typeof ((typeof 1)) //returns "string"
//Booleans
typeof (true) //returns "boolean"
typeof (false) //returns "boolean"
//Symbols
typeof (Symbol()) //returns "symbol"
typeof (Symbol('foo')) //returns "symbol"
//Undefined
typeof (undefined) //returns "undefined"
typeof (declaredButUndefinedVariable) //returns "undefined"
typeof (undeclaredVariable) //returns "undefined"
//Objects
typeof ({a:1}) //returns "object"
typeof ([1, 2, 4]) //returns "object"
//Functions
typeof (function(){}) //returns "function"
typeof (Math.sin) //returns "function"
همانطور که میبینیم، تقریباً همهٔ عبارات از نظر اپراتور typeof
در 7 نوع دیتا تایپ جاوااسکریپت خلاصه میشوند که برای کسب اطلاعات بیشتر میتوانید به آموزش آشنایی با انواع Data Type در زبان برنامهنویسی جاوااسکریپت مراجعه نمایید. (به خاطر داشته باشید همواره مقدار NaN به عنوان یک عدد، البته از نوع نامشخص آن، در نظر گرفته میشود.)
اگر متغیری را به اپراتور typeof
پاس دهیم که تعریف شده اما مقداری برای آن در نظر گرفته نشده باشد، اپراتور typeof
خروجی undefined را نشان میدهد بدین معنا که متغیر ما هنوز بلاتکلیف است یا بهتر بگوییم مقدار مشخصی ندارد. همچنین اگر متغیری که نه تعریف شده و نه مقداری دارد را به typeof
پاس دهیم، باز هم عبارت undefined را مشاهده خواهیم کرد:
var num;
typeof num; //returns "undefined"
typeof c; //returns "undefined"
به کمک اپراتور delete
میتوان پراپرتی خاصی را از یک آبجکت حذف کرد:
delete myObject.firstProperty;
delete myObject['firstProperty'];
هر دو عبارت بالا، مشابه بوده و یک کار را انجام میدهند و آن هم چیزی نیست جز حذف پراپرتی firstProperty
از آبجکت myObject
که بدین ترتیب این پراپرتی و تمامی مقادیر/رفرنسهای آن به طور کامل از آبجکت حذف میشوند به طوری که اگر اپراتور delete
در کار خود موفق شود، خروجی true
را به عنوان خروجی نمایش میدهد و اگر ناموفق باشد، خروجی false
نشان داده میشود (توجه داشته باشید که این اپراتور فقط بر روی پراپرتیهای یک آبجکت اثر میگذارد و استفاده از آن بر روی متغیرها بیفایده خواهد بود.)
اپراتور %
باقیماندهٔ تقسیم دو عدد بر هم را به عنوان خروجی نمایش میدهد به طوری که داریم:
var remainder = 23 % 7; //returns 2
همانطور که مشخص است، تقسیم عدد 23 بر 7 دارای خارجقسمت 3 و باقیماندهٔ 2 خواهد بود و این اپراتور نیز دقیقاً باقیماندهٔ مورد نظر را نمایش میدهد.
اپراتور >>
بیتهای یک عدد را به سمت چپ شیفت میکند که برای درک بهتر کاربرد این اپراتور، مثال زیر را مد نظر قرار میدهیم:
var leftShift = 9 << 2;
console.log(leftShift); //returns 36
اولین خط این کد به مفسر جاوااسکریپت دستور میدهد که عدد 9 را به تعداد 2 بیت به سمت چپ شیفت کند و از همین روی >>
بدینگونه عمل میکند که عدد سمت چپ خود را به تعداد بیتهای عدد سمت راست شیفت میکند.
در منطق باینری، عدد 9 به شکل 1001 تعریف میشود و زمانی که بخواهیم این عدد را به تعداد 2 بیت به سمت چپ شیفت کنیم، کل اعداد آن را دو خانه به سمت چپ منتقل میکنیم و به جای خانههای خالی 0 میگذاریم و بدین ترتیب عدد 1001 به 100100 تبدیل میشود. در آخر، جاوااسکریپت عدد معادل در منطق دهدهی را محاسبه میکند و به عنوان خروجی نمایش میدهد (100100 در منطق باینری برابر با عدد 36 در منطق دهدهی است.)
اپراتور <<
نیز همانند مورد قبلی، عملیات شیفت را بر روی اعداد در مبنای ۲ انجام میدهد اما به جای شیفت به چپ، آن را به سمت راست شیفت میکند که در این بین هر بیت اضافه که به راست شیفت میشود حذف خواهد شد. فرض کنیم که همان عدد 9 را بخواهیم به کمک این اپراتور به سمت راست شیفت کنیم. عدد 9 در منطق باینری به شکل 1001 نمایش داده میشود و اگر بخواهیم این عدد را به تعداد دو بیت به سمت راست شیفت کنیم، دو بیت اول از سمت راست (یعنی 1 و 0) حذف میشوند. از طرف چپ نیز همان بیتی که در گذشته قرار داشته، به تعداد بیتهای حذف شده (در اینجا دو بار) تکرار میشود:
9 (base 10) = 00000000000000000000000000001001 (base 2)
9>>2 (base 10) = 00000000000000000000000000000010 (base 2) = 2 (base 10)
همانطور که میبینیم، دو بیت از سمت راست حذف شده و از سمت چپ نیز دو بیت 0 اضافه شده است.
اگر بخواهیم از وجود یک پراپرتی، تابع از پیش تعریف شده یا عضو در داخل یک آبجکت مطمئن شویم، از اپراتور in
استفاده خواهیم کرد:
//Arrays
var trees = ["redwood", "cedar", "oak", "maple"];
0 in trees //returns true
3 in trees //returns true
6 in trees //returns false
"oak" in trees //returns false (you must specify the index number, not the value at that index)
"length" in trees //returns true (length is an Array property)
//Predefined objects
"PI" in Math //returns true
//Custom objects
var myCar = {brand: "Honda", model: "Accord", year: 1998};
"brand" in myCar //returns true
"model" in myCar //returns true
در بخش اول، آرایهای دلخواه تعریف کردهایم و با استفاده از اپراتور in
میتوانیم بررسی کنیم که برای مثال آیا در ایندکس سوم عضوی وجود دارد یا خیر و میبینیم که برای اعضای ۰ و ۳ مقدار true
بازگردانده میشود اما از آنجا که اندیس ۶ وجود خارجی ندارد، مقدار false
در نظر گرفته شده است. اگر در اینجا به جای شمارهٔ اندیس آرایه، محتوا یا مقدار آن خانه را از اپراتور in
بخواهیم، خروجی false
خواهد بود (مثلاً به جای 2 از "oak"
استفاده کنیم.)
همانطور که گفته شد، این اپراتور میتواند توابع از پیش تعریف شده یا پراپرتیها را نیز مشخص کند و از آنجایی که "PI"
یا همان عدد 3/14 به طور پیشفرض در کلاس Math
جاوااسکریپت تعریف شده، خروجی اپراتور in
مثبت یا به عبارتی true
خواهد بود.
در بخش آخر نیز یک آبجکت دلخواه تحت عنوان myCar
با سه پراپرتی مختلف ایجاد کردهایم که استفاده از اپراتور in
بر روی این پراپرتیها خروجی true
خواهد داشت اما در عین حال اگر به جای نام پراپرتی یکی از مقادیر آن مثلاً "Honda"
را از این اپراتور بخواهیم (دقیقاً مشابه بخش اول و عملکرد این اپراتور در آرایهها)، خروجی false
خواهد بود.
در بررسی برابری و یا نابرابری دو مقدار اگر آنها از یک تایپ (نوع) نباشند، جاوااسکریپت ابتدا آنها را به یک تایپ یکسان تبدیل کرده و سپس عملیات مقایسه را انجام میدهد. برای مثال، اگر استرینگ "1" را با عدد 1 بخواهیم مقایسه کنیم، جاوااسکریپت ابتدا هر دو را به عدد تبدیل کرده و سپس آنها را با یکدیگر مقایسه میکند اما در اپراتور ===
عملیات تبدیل متغیر صورت نمی گیرد و مقادیر به همان شکلی که هستند با یکدیگر مقایسه میشوند:
3 == "3" //returns true
3 === "3" //returns false
همانطور که میبینیم، در مقایسهٔ اول از اپراتور برابری عادی ==
استفاده شده و هر دو مقدار، پس از تبدیل به تایپی یکسان، با یکدیگر برابر در نظر گرفته میشوند اما زمانی که از اپراتور برابری مطلق یا ===
استفاده کنیم، خروجی false
خواهد بود.
کاربرد اصلی اپراتور &&
در برقراری شرطها است. زمانی که از این اپراتور استفاده میکنیم، این بدان معنا است که تمامی شروط باید همزمان برقرار باشند و حتی اگر یکی از آنها false
باشد، خروجی کل دستور برابر با false
خواهد بود:
x < 10 && y > 1
در مثال بالا، به جاوااسکریپت دستور دادهایم که متغیر x
حتماً باید کوچکتر از 10 بوده و در عین حال متغیر y
نیز باید بزرگتر از 1 باشد که اگر این دو شرط به صورت همزمان برقرار باشند، خروجی اپراتور &&
برابر با true
خواهد بود و در غیر این صورت false
میشود.
در بررسی شرطها، به کمک اپراتور ||
به جاوااسکریپت میگوییم که حتی اگر یکی از شروط نیز برقرار بود، خروجی true
را نمایش دهد. به عبارتی، بر خلاف &&
اصلاً نیازی نیست که تمامی شرطها به طور همزمان برقرار باشند و حتی اگر یکی از شروط نیز صادق بود، خروجی کل آن عبارت برابر با true
خواهد بود:
(x == 5 || y == 10)
تکه کد بالا به مفسر جاوااسکریپت دستور میدهد که اگر x
برابر با 5 بود یا آنکه y
برابر با 10 بود، کل آن عبارت را به عنوان true
فرض کند به طوری که حتی اگر x
برابر با ۵ باشد اما y
برابر با 10 نباشد، باز هم این اپراتور خروجی true
را نمایش خواهد داد.
اپراتور ?
در کنار :
تنها اپراتور جاوااسکریپت است که سه عملوند جداگانه دریافت میکند و عموماً از این اپراتور به جای ساختار if
استفاده میشود که میتواند با توجه به شرط در نظر گرفته شده یکی از دو مقدار تعریفشده را به عنوان خروجی ریترن کند:
var voteable = (age > 18) ? "Old enough":"Too young";
در اینجا فرض کنید که از قبل متغیری به نام age
تعریف کردهایم و قصد داریم سن یک کاربر را در آن ذخیره کنیم. اکنون با استفاده از این اپراتورها و متغیر voteable
میخواهیم بررسی کنیم ببینیم که آیا این کاربر میتواند در انتخابات شرکت کند یا خیر. اولین عملوند که باید پیش از ?
نوشته شود شرط اصلی است که در این مثال age < 18
بررسی میکند که آیا مقدار age
بیشتر از 18 است یا خیر. پس از علامت سؤال هم دو عبارت قرار میدهیم که در حقیقت خروجیهای احتمالی هستند به طوری که اگر شرط برابر true
باشد، اولین خروجی انتخاب میشود و اگر false
باشد، دومین خروجی که پس از علامت :
درج شده نمایش داده میشود.
برای درک بهتر این موضوع، در اینجا فرض کنیم که مقدار متغیر age
برابر با ۱۵ است که بدین ترتیب شرط اپراتور برابر با false
خواهد بود و دومین خروجی یعنی «Too young» نمایش داده میشود اما اگر مقدار این متغیر ۳۰ باشد، خروجی برابر true
بوده و عبارت «Old enough» به عنوان خروجی نمایش داده خواهد شد.
اپراتورهای تخصیص که در ادامه بررسی میکنیم، همگی به یک شکل مشترک عمل میکنند به طوری که در ابتدا عملیاتی را بر روی متغیر اول و دوم اجرا میکنند و سپس پاسخ نهایی را مستقیماً به داخل اپراتور اول میریزند که بدین ترتیب دیگر نیازی به یک متغیر سوم برای نگاه داشتن خروجی عملیات نیست.
اپراتور =+
متغیر اول را با متغیر دوم جمع کرده و نتیجه را در متغیر اول ذخیره میکند:
var x = 3;
var y = 2;
x += y; //meaning: x = x + y;
console.log(x); //returns 5
در مثال بالا، زمانی که از اپراتور =+
استفاده میکنیم، جاوااسکریپت ابتدا x
را با y
جمع میکند و سپس خروجی آن را مستقیماً به x
تخصیص میدهد و به همین دلیل هم زمانی که مقدار x
را از جاوااسکریپت میخواهیم، عدد 5 (مجموع 2 + 3) را به ما نمایش میدهد.
عملکرد اپراتور =-
نیز دقیقاً عکس اپراتور بالا است بدین شکل که عمل تفریق را انجام میدهد:
var x = 3;
var y = 2;
x -= y; //meaning: x = x - y;
console.log(x); //returns 1
سایر اپراتورهای تخصیص که در زیر آمدهاند نیز بسته به علامتی که قبل از =
قرار گرفته است، عملکردی قابلپیشبینی دارند:
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
به بیانی دیگر، این اپراتورها علامت پیش از مساوی مانند *
را بین متغیر اول و دومی که در اطرافشان قرار دارند اجرا میکنند سپس نتیجهٔ نهایی را در متغیر اول ذخیره میکنند که اصطلاحاً این کار را Overwrite میگویند (با استفاده از متغیرهای تخصیص بدین شکل، میتوانیم تعداد خطوط کدها را کاهش دهیم و به شکل بهینهتری برنامه را نوشته و اجرا کنیم.)
پیش از هر چیز، باید گفت که این اپراتور کاملاً با علامتی که در داخل آرایهها، آبجکتها، آرگومانهای فانکشن و یا پارامترها استفاده میشود تفاوت دارد و به همین دلیل نباید اپراتور ,
را با یک کامای ساده اشتباه گرفت. در واقع، عملکرد ,
بدین شکل است که از سمت چپ به راست تمامی عملوندها و اِکسپرشنها را محاسبه میکند و سپس مقدار آخرین عملوند یا اِکسپرشن (سمت راست) را نمایش میدهد و به کمک این اپراتور میتوانیم در جاهایی که فقط امکان تعریف یک اِکسپرشن وجود دارد، چندین اِکسپرشن را به یکدیگر متصل کرده و به عنوان یک اِکسپرشن بزرگتر استفاده کنیم. رایجترین کاربرد این اپراتور تعریف چندین پارامتر برای لوپ (حلقه) است. برای روشنتر شدن موضوع، نمونههای زیر را در نظر بگیرید:
a = b = 3, c = 4;
مثال بالا دارای دو بخش است که توسط اپراتور ,
از هم جدا شدهاند اما به عنوان یک اِکسپرشن، در یک خط نوشته شدهاند که در بخش اول مقدار 3 به متغیر b
اختصاص داده شده و بعد از آن مقدار b
به متغیر a
داده میشود و در نهایت هر دوی آنها دارای مقدار 3 میشوند و در ادامه مقدار 4 نیز به متغیر c
داده میشود. به عنوان مثالی دیگر داریم:
x = (y = 5, z = 6); //returns 6 in console
console.log(x); //returns 6
در تکه کد بالا میخواهیم متغیر x
را مقداردهی کنیم اما در جلوی اپراتور =
یک پرانتز با دو اِکسپرشن متفاوت قرار دادهایم که با استفاده از اپراتور ,
از هم جدا شدهاند. همانطور که گفته شد، این اپراتور تمامی اِکسپرشنهای سمت چپ را محاسبه میکند و تنها مقدار آخرین اِکسپرشن را به عنوان خروجی نمایش میدهد. از همین روی، در داخل پرانتز ابتدا مقدار y
برابر 5 قرار داده میشود و z
نیز مقدار 6 را به خود اختصاص میدهد سپس از آنجایی که آخرین اِکسپرشن z = 6
است، خروجی کلی پرانتز برابر با z = 6
خواهد بود و بدین ترتیب کد به صورت x = z = 6
در خواهد آمد و نتیجتاً خروجی نهایی x
نیز برابر با 6 خواهد بود.