مقدمه

یک عملگر (operator) نمادی است که برای انجام عمل خاصی روی مقادیر کاربرد دارد. مقادیری که عملگر روی آنها اِعمال می‌شود، عملوند (operand) نامیده می‌شوند و می‌توانند به صورت مقادیر لیترال و یا در قالب متغیرها و ثوابت در عبارات ظاهر شوند. عملگرهای حسابی، مقایسه‌ای، منطقی و بیتی مهمترین و پرکاربردترین عملگرهای جاوااسکریپت هستند. در این درس، این عملگرها را معرفی و بررسی می‌کنیم.

اصطلاحات مربوط به عملگرها

قبل از شروع، اجازه دهید در مورد چند اصطلاح مربوط به درس جاری توضیح کوتاهی بدهیم.

  • عملگر: یک عملگر یا operator نمادی است که عمل مشخصی را روی مقادیر انجام می‌دهد. عملگرها ماهیتاً توابعی هستند که نمادهایی برای آنها در نظر گرفته شده است.
  • عملوند: مقادیری که عملگرها روی آنها عمل می‌کنند عملوند یا operand نام دارند. برای مثال در عبارت a * b عملوندها a و b هستند که عمل ضرب که با نماد * نمایش داده می‌شود، روی آنها انجام می‌شود.
  • عملگر unary: عملگری که تنها یک عملوند داشته باشد، عملگر unary نامیده می‌شود.
  • عملگر binary: عملگری که دو عملوند داشته باشد، یک عملگر binary گفته می‌شود.
  • عملگر ternary: عملگری که دارای سه عملوند باشد، عملگر ternary نامیده می‌شود. در جاوااسکریپت فقط یک عملگر ternary داریم که هنگام بررسی ساختارهای شرطی آن را خواهیم دید.

در ادامه، به بررسی انواع عملگرهای جاوااسکریپت می‌پردازیم و به‌ویژه قوانین تبدیل را نیز در مورد آنها خواهیم دید.

عملگرهای حسابی

عملگرهای حسابی (arithmetic operators) همانطور که لفظ می‌رساند، برای انجام اعمال محاسباتی روی اعداد به کار می‌روند. در جدول زیر لیست این عملگرها را می‌بینید.

نام عملگر نماد عملگر مثال
عملگر جمع (addition) + let x = 5 + 7; // x=12
عملگر تفریق (subtraction) - let x = 10 – 2; // x=8
عملگر ضرب (multiplication) * let x = 5 * 6; // x=30
عملگر تقسیم (division) / let x = 10 / 4; // x=2.5
let y = 20 / 5; // y=4
عملگر توان (exponentiation) ** let x = 2 ** 5; // x=32
let z = 8 ** (1 / 3); // z=2
عملگر باقیمانده‌ی تقسیم (modulus) % let x = 30 % 4; // x=2
عملگر افزایند‌ه (incrementor) ++ let x = 10; x++; // x=11
عملگر کاهند‌ه (decrementor) -- let x = 10; x--; //x=9

همه‌ی عملگرهای جدول بالا (به‌جز عملگر +) انتظار عملوندهای عددی دارند و بنابراین، اگر از مقادیر غیر عددی به عنوان عملوندهای آنها استفاده شود، به طور خودکار و ضمنی به مقادیر عددی معادلشان تبدیل می‌شوند. اما عملگر + به بررسی جداگانه نیاز دارد.

نقش عملگر +

نماد + می‌تواند به‌عنوان یک عملگر حسابی برای عمل جمع (addition)، یک عملگر الحاق (concatenation) برای چسباندن رشته‌ها به هم و یا به عنوان یک عملگر تبدیل برای تبدیل مقادیر غیر عددی به عددی به کار رود. چیزی که نوع این عملگر را تعیین می‌کند، عملوندهای آن است.

  • در عبارت a + b اگر یک یا دو عملوند از نوع string باشد، نماد + به عنوان عملگر الحاق عمل کرده و رشته‌ای را برمی‌گرداند که حاصل چسباندن دو مقدار رشته‌ای به هم است.
  • در عبارت a + b اگر هیچ‌کدام از عملوندها از نوع string نباشد، نماد + به‌عنوان عملگر حسابی جمع عمل کرده که عملوندها را (در صورت نیاز) به عدد تبدیل کرده و آنها را با هم جمع می‌کند.
  • عملگر + در فرم unary مثل تابع تبدیل Number() عمل می‌کند. یعنی مثلاً +true برابر با 1 خواهد بود.

مثال زیر را ببینید.

> 5 + 6
11
> 5 + "6"
'56'
> "Hello" + " World!"
Hello World!
> true + false 
1
          

عملگر تخصیص

در جبر و ریاضیات از نماد = به عنوان عملگر تساوی (equality) استفاده می‌شود و عبارتی مثل a = b به این معناست که a و b دارای مقدار برابر هستند. اما در جاوااسکریپت این نماد برای تخصیص یک مقدار به یک متغیر کاربرد دارد و عملگر تخصیص (assignment) نامیده می‌شود. پس عبارت a = b در جاوااسکریپت به این معناست که مقدار متغیر یا لیترال b به متغیر a تخصیص داده شود. از ترکیب عملگر تخصیص با عملگرهای حسابی ‌می‌توان برای خلاصه‌نویسی برخی عبارات استفاده کرد. جدول زیر را ببینید.

عبارت معادل
x += y x = x + y
x -= y x = x - y
x *= y x = x * y
x /= y x = x / y
x %= y x = x % y
x **= y x = x** y

در جاوااسکریپت هر عملگری یک مقدار برمی‌گرداند و عملگر تخصیص هم از این قاعده مستثنی نیست. عبارت x = value ابتدا value را به x تخصیص داده و سپس آن را برمی‌گرداند. برای روشن شدن موضوع، به مثال زیر دقت کنید.

Copy Icon JAVASCRIPT
let a = 1;
let b = 2;
            
let c = 3 - (a = b + 1);
            
console.log(a); // 3
console.log(c); // 0

در اینجا مقدار عبارت (a = b + 1) مقداری است که به a نسبت داده می‌شود؛ یعنی 3. البته این مثال را فقط از این جهت ارائه دادیم که ممکن است با چنین کدهایی در برخی کتابخانه‌های جاوااسکریپتی مواجه شوید اما به طور کلی، نوشتن چنین کدهایی اصلاً توصیه نمی‌شود.

عملگرهای مفایسه‌ای

گروه دیگری از عملگرهای جاوااسکریپت که برای مقایسه‌ی مقادیر به کار می‌روند، عملگرهای مقایسه‌ای (comparisional) نامیده ‌می‌شوند. این عملگرها در جدول زیر آورده شده‌اند.

نام عملگر نماد عملگر مثال
عملگر برابری (equality) == let b = 10 == 5; // b=false
let b = undefined == null; // b=true
عملگر برابری مقدار و نوع (strict equality) === let b = 10 === 10; // b=true
let b = undefined === null; // b=false
عملگر نابرابری (not equality) != let b = 10 != 5; // b=true
let b = undefined != null; // b=false
عملگر نابرابری مقدار یا نوع (not strict equality) !== let b = 10 !== 5; // b=true
let b = undefined !== null; // b=true
عملگر بزرگتری (greater than) > let b = 10 > 5; // b=true
let b = "hello" > "bye"; // b=false
عملگر کوچکتری (less than) < let b = 10 < 5; // b=false
let b = "hello" < "bye"; // b=true
عملگر بزرگتر یا مساوی (greater than or equal to) >= let b = 10 >= 5; // b=true
عملگر کوچکتر یا مساوی (less than or equal to) <= let b = 10 <= 10; // b=true

اولین مطلبی که باید در مورد عملگرهای مقایسه‌ای بدانید این است که نتیجه‌ی حاصل از یک عمل مقایسه‌ای همیشه یک بولین است. و مطلب مهم دیگر اینکه این عملگرها هم مثل عملگرهای حسابی به عملوندهای عددی نیاز دارند. بنابراین، اگر از مقادیر غیر عددی به عنوان علموند استفاده کنیم، به عدد تبدیل می‌شوند. البته مقادیر string در این بین یک استثنا محسوب می‌شوند که عملگرهای مقایسه‌ای روی آنها به شکل متفاوتی عمل می‌کنند.

مقایسه رشته‌ها

در جدول بالا حاصل عبارت "hello" < "bye" به مقدار true منجر شده است. اما چرا و بر اساس چه قاعده‌ای؟

جاوااسکریپت رشته‌ها را بر اساس ترتیب دیکشنری (یا lexicographical order) مقایسه می‌کند. یعنی رشته‌ها را کاراکتر به کاراکتر مقایسه می‌کند. اگر نتیجه‌ی مقایسه‌ی کاراکترهای اول این باشد که یکی از آنها بزرگتر از دیگری باشد، مقایسه به پایان می‌رسد و در صورت یکی بودن کاراکترها، کاراکترهای بعدی مقایسه می‌شوند.

البته توجه داشته باشید که عامل تعیین‌کننده در مقایسه‌ی کاراکترها واقعاً ترتیب الفبایی آنها نیست، بلکه کد متناظر آنها در مجموعه کاراکتری Unicode ملاک مقایسه است. به همین دلیل است که کاراکترهای A و a یکسان نیستند، بلکه a بزرگتر است.

در ضمن، اگر فقط یکی از عملوندها از نوع string باشد، مطابق روال معمول، هر دو به عدد تبدیل شده و مقایسه می‌شوند. مثال زیر را ببینید.

> true > ""
true
> false > ""
false
> 1 > "HI" 
false
          

عملگرهای برابری و نابرابری

چهار عملگر ابتدایی جدول بالا عملگرهایی هستند که عملوندهایشان را از نظر برابری یا نابرابری مقایسه می‌کنند. عملگر == مطابق روال معمول، عملوندهایش را به عدد تبدیل کرده و آنها را با هم مقایسه می‌کند.

> true == 1
true
$ 0 == false 
true
> 0 == ' '
true
          

اما گاهی اوقات ممکن است نخواهیم مقادیری مثل 0 و false یکی محسوب شوند. در این صورت، می‌نوانیم از عملگر === استفاده کنیم که مقایسه را بدون تبدیل نوع انجام می‌دهد و بنابراین، فقط وقتی مقدار true را برمی‌گرداند که دو مقدار هم از یک نوع و هم برابر باشند.

> 0 === false
false
> 1 === true 
false
          

در مورد عملگر == یک استثنای مهم وجود دارد که باید آن را در نظر داشته باشید و آن این است که از نظر این عملگر، مقادیر null و undefined با هم برابرند اما با هیچ مقدار دیگری برابر نیستند. یعنی undefined == null برابر با true است اما هر عبارت a == b دیگر که در آن یکی از a و b مقدار null یا undefined باشد، برابر با false خواهد بود. طبیعتاً این موضوع در مورد عملگر === صادق نیست؛ چون null و undefined از دو نوع مخنلف هستند و بنابراین، عبارت null === undefined با false ارزیابی می‌شود.

البته در مورد عملگر === هم نکته‌ای هست که باید بدانید و آن این است که عبارت NaN === NaN برای این عملگر با false ارزیابی می‌شود. برای چنین مقایسه‌هایی بهتر است از تابع isNaN استفاده کنیم. این تابع را در درس بعدی معرفی می‌کنیم.

عملگرهای منطقی

در جاوااسکریپت، چهار عملگر منطقی (logical) داریم که در این بخش آنها را معرفی می‌کنیم. عملگرهای منطقی جاوااسکریپت می‌توانند عملوندهای از هر نوع، اعم از بولین و غیر بولین، داشته باشند و خروجی آنها هم می‌تواند از هر نوعی باشد.

نام عملگر نماد عملگر توضیح
Disjunction || این عملگر، عملوندهایش را از چپ به راست ارزیابی کرده و اولین مقدار Truthy را برمی‌گرداند. اگر هیچ از یک از عملوندها Truthy نباشند، آخرین مقدار را برمی‌گرداند.
Conjunction && این عملگر، عملوندهایش را از چپ به راست ارزیابی کرده و اولین مقدار Falsy را برمی‌گرداند. اگر هیچ یک از عملوندها Falsy نباشند، آخرین مقدار را برمی‌گرداند.
Negation ! این عملگر فقط یک عملوند دارد که آن را به بولین تبدیل کرده و سپس، معکوس آن را برمی‌گرداند.
Nulish Coalescing ?? این عملگر از بین عملوندهای خود، اولین مقداری که مخالف null و undefined باشد را برمی گرداند. اگر همه‌ی عملوندها null یا undefined باشند، آخرین مقدار را برمی‌گرداند.

اگر سابقه‌ی کار با زبان‌های دیگر را داشته باشید، شاید عملگرهای منطقی جاوااسکریپت و کارکردشان برایتان تازگی داشته باشد. در اکثر زبان‌ها، عملگرهای منطقی، حکم عملگرهای منطقی AND و OR و NOT را دارند که فقط روی مقادیر بولین عمل می‌کنند و مقادیر بولین هم برمی‌گردانند. اما این عملگرها در جاوااسکریپت، نقش کلی تری دارند و قدرتمندتر هستند. مثال زیر را ببینید.

>>> 1 || 0 
1 
>>> 0 || null || 5 || 8
5
>>> null || undefined || 0
0 
>>> 5 && 8 && 0 && "Hi"
0 
>>> true && 10 && undefined && "Hi"
undefined 
>>> !0
true 
>>> !(10 > 5)
false 
>>> null ?? undefined ?? 0 ?? null
0
>>> null ?? undefined ?? undefined ?? null
null 
            

عملگرهای بیتی

عملگرهای بیتی (bitwise operators) روی اعداد صحیح 32 بیتی اعمال شده و یک عدد صحیح را به عنوان نتیجه برمی‌گردانند. ابتدا هر یک از عملوندها به معادل خود در مبنای 2 یعنی به فرم یک عدد باینری تبدیل شده و سپس، بیت‌های هم‌مکان با هم مقایسه می‌شوند (یعنی بیت اول عملوند اول با بیت اول عملوند دوم، بیت دوم با بیت دوم و الی آخر). نتیجه‌ی هر مقایسه بسته به نوع عملوند مقدار صفر یا یک است و به این ترتیب، یک رشته‌بیت (bit string) به عنوان نتیجه حاصل می‌شود که البته معادل آن در مبنای 10 برگردانده می‌شود. در جدول زیر لیست این عملگرها آورده شده است.

نام عملگر نماد عملگر توضیح
AND & در هر مقایسه اگر هر دو بیت برابر با 1 باشند، مقدار 1 و در غیر این صورت صفر را برمی‌گرداند.
OR | در هر مقایسه اگر حداقل یکی از دو بیت برابر با 1 باشند، مقدار 1 و گرنه مقدار صفر را برمی‌گرداند.
XOR ^ اگر بیت‌های مورد مقایسه یکسان باشند، یعنی هر دو 1 یا هر دو صفر باشند، مقدار صفر و در غیر این صورت مقدار 1 را برمی‌گرداند.
NOT ~ بیت های عملوند خود را معکوس می‌کند. یعنی 1 را به صفر و صفر را به 1 تبدیل می‌کند.
Left Shift a<<b a را در فرم باینری به اندازه‌ی b واحد به چپ شیفت می‌کند. به عبارت دیگر، هر بیت به اندازه‌ی b واحد به سمت چپ جابجا می‌شود.
Right Shift a>>b a را در فرم باینری به اندازه‌ی b واحد به راست شیفت می‌کند.

در کدهای زیر می‌توانید عملکرد عملگرهای بیتی را در عمل ببینید.

Copy Icon JAVASCRIPT
let a = 5;           // 00000000000000000000000000000101
let b = 3;           // 00000000000000000000000000000011
            
console.log(a & b);  // 00000000000000000000000000000001 = 1 
console.log(a | b);  // 00000000000000000000000000000111 = 7
console.log(a ^ b);  // 00000000000000000000000000000110 = 6
console.log(a << b); // 00000000000000000000000000101000 = 40