همهی ما عملگرهای مقایسهای را در ریاضی یاد گرفتهایم:
- بزرگتر/کوچکتر :
a > b
,a < b
. - بزرگتر مساوی / کوچکتر مساوی :
a >= b
,a <= b
. - برابری:
a == b
(حواستان باشد که برای مقایسه باید دو علامت مساوی پشت سر هم بنویسید. اگر فقط یک علامت مساوی بنویسید (a = b
) برای ریختن مقدار درون متغیّر است، نه مقایسه). - نابرابری: در ریاضی علامت نابرابری ≠ است، اما به دلیل عدم وجود این علامت در صفحهکلید، در جاوااسکریپت به صورت
!=
نوشته میشود. مثلاًa != b
.
همیشه نتیجهی مقایسه بولین است
مانند همهی عملگرهای دیگر، عملگر مقایسهای هم مقدار برمی گرداند؛ که این مقدار همیشه از نوع بولین است.
true
– به معنیبله
یاصحیح
.false
– به معنیخیر
یاغلط
.
برای مثال:
alert( 2 > 1 ); // true (صحیح)
alert( 2 == 1 ); // false (غلط)
alert( 2 != 1 ); // true (صحیح)
میتوان نتیجهی مقایسه را مانند هر مقدار دیگری درون یک متغیر ریخت:
let result = 5 > 4; // نتیجه ی مقایسه را درون متغیر result می ریزد
alert( result ); // true
مقایسهی رشتهها
بزرگتر یا کوچک بودن دو رشته طبق حروف الفبا تعیین میشود.
به عبارت دیگر، رشته حرف به حرف مقایسه میشود.
برای مثال:
alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Be' > 'Bee' ); // false
روش مقایسهی رشتهها به این صورت است:
- اوّلین نویسهی رشتهها (اوّلین حرف) با هم مقایسه میشود.
- اگر اوّلین نویسهی رشتهی اوّل بزرگتر (یا کوچکتر) از رشتهی دیگر بود، پس آن رشته از دیگر بزرگتر (کوچکتر) است. اینجا مقایسه تمام میشود.
- در غیر این صورت، یعنی اگر دو کاراکتر با هم برابر باشند، به همان روش بالا نویسههای دوم دو رشته با هم مقایسه میشود.
- این کار تا رسیدن به انتهای یکی از رشتهها تکرار میشود.
- اگر هر دو رشته با هم به انتها برسند و طول یکسانی داشته باشند، پس با هم برابر هستند. در غیر این صورت رشتهی طولانی تر بزرگتر است.
این همان روشی است که طبق آن، لیست اسامی را به ترتیب حروف الفبا مرتّب میکنند.
در مثال های بالا، مقایسه "Z" > "A"
در قدم اول به نتیجه میرسد در حالیکه رشتههای "Glow"
و "Glee"
کاراکتر به کاراکتر با هم مقایسه میشوند:
G
باG
برابر است.l
باl
برابر است.o
بزرگتر ازe
است. مقایسه در اینجا به پایان میرسد. رشتهی اوّل بزرگتر است.
مقایسهی رشتهها طبق فرهنگ لغت نیست، بلکه طبق کدِ نویسههاست.
شیوهای که در بالا توضیح داده شد تقریبا شبیه به ترتیبی است که در دفترچه تلفن و فرهنگ لغت داریم، امّا دقیقاً یکسان نیست.
مثلاً، بزرگی و کوچکی حروف در مقایسهی رشتهها اهمیت دارد. حرف بزرگ "M"
با حالت کوچکِ همان حرف "m"
برابر نیست. کدامیک بزرگتر است؟! حرف کوچک "m"
! چرا؟ چون در دنیای کامپیوتر به هر حرف و نویسهای یک کدِ عددی اختصاص پیدا میکند، و مقایسهی رشتهها با مقایسهی آن کدها انجام میگیرد، و به صورت کلّی کُد حروف کوچک انگلیسی بزرگتر از حروف بزرگ است. در آموزشهای بعدی بیشتر در این باره صحبت میکنیم.
مقایسهی دیتاتایپهای مختلف
اگر مقادیری که با هم مقایسه میشود دیتاتایپ متفاوتی داشته باشند، جاوااسکریپت آنها را به عدد تبدیل میکند.
برای مثال:
alert( '2' > 1 ); // true, رشته "۲" به عدد ۲ تبدیل می شود
alert( '01' == 1 ); // true, رشته ی "۰۱" به عدد ۱ تبدیل می شود
برای مقادیر بولین، true
به ۰
و false
به ۱
تبدیل می شود.
برای نمونه:
alert( true == 1 ); // true
alert( false == 0 ); // true
یک نتیجهی بامزه
این امکانپذیر است که همزمان:
- دو مقدار با هم برابر باشند.
- یکی از آنها به عنوان بولین برابر با
true
شود و دیگری به عنوان بولین برابر باfalse
شود!
let a = 0;
alert( Boolean(a) ); // false
let b = "0";
alert( Boolean(b) ); // true
alert(a == b); // true!
مثال:
از زاویه دید جاوااسکریپتی، این نتیجه کاملاً عادی است. در مقایسه هر دو طرف به عدد تبدیل میشود (به همین خاطر "۰"
می شود ۰
) درحالیکه تبدیل مستقیم این مقادیر به بولین
از قوانین دیگری پیروی میکند.
بررسی برابری
عملگر مقایسهایِ ==
یک مشکل بزرگ دارد. این مقایسه تفاوت میان ۰
و false
را تشخیص نمیدهد:
alert( 0 == false ); // true
با رشتهی خالی نیز همین مشکل را داریم:
alert( '' == false ); // true
از آنجاییکه عملگر ==
هنگام بررسی تساوی، مقادیر را به عدد تبدیل می کند. رشتهی خالی و false
، هر دو به ۰
تبدیل می شوند.
برای آن که بتوانیم تفاوت میان ۰
و false
را تشخیص دهیم، باید چه کار کنیم؟
عملگر ===
برابری دو مقدار را بدون آن که آنها را تبدیل کند، بررسی میکند.
به عبارت دیگر، اگر a
و b
دیتاتایپ متفاوتی داشته باشند، عبارت a === b
مقدار false
را بر میگرداند بدون آن که بخواهد دیتاتایپ آنها را تغییر دهد.
بیایید این را امتحان کنیم:
alert( 0 === false ); // false, چون این دو دیتاتایپ های مختلفی دارند
جالب است بدانید که همین قضیه در مورد نابرابری نیز وجود دارد. یعنی عملگر !=
مانند ==
دو طرف را به عدد تبدیل میکند، ولی !==
مانند ===
دیتاتایپ را عوض نمیکند، و در صورتی که دیتاتایپ متفاوت باشد false بر میگرداند.
alert( 0 !== false ); // true
//درست است که مقادیر عددی این دو با هم برابرند اما تایپ های متفاوتی دارند
اگر به این روش دو مقدار را با هم مقایسه کنید، کد طولانیتری مینویسید، اما جای اشتباه کمتری باقی میگذارد.
مقایسهی null و undefined
در مورد مقایسهی null
یا undefined
با سایر مقادیر نکتهای بسیار مهم وجود دارد، که مورد بررسی قرار میدهیم.
بررسی برابری با عملگر ===
این مقادیر با هم متفاوتند و رفتار جداگانهای نشان میدهند. چون هر کدام آنها دیتاتایپ متفاوتی دارند.
alert( null === undefined ); // false
بررسی برابری با عملگر ==
در این حالت قانون خاص و مهمی وجود دارد: دو مقدار null
و undefined
با هم برابر هستند اما با هیچ مقدار دیگری برابر نیستند.
alert( null == undefined ); // true
عملیات ریاضی و سایر عملگرهای مقایسهای < > >= <=
در این حالت null/undefined
به عدد تبدیل میشود: null
به ۰
تبدیل میشود و undefined
به NaN
تبدیل میشود.
حالا بیایید یک سری اتّفاقات جالب را که طبق این قوانین رخ میدهد بررسی کنیم و مهمتر از آن اینکه در دام آنها نیفتیم.
نتیجهی عجیب: null
در مقابل ۰
بیایید null
را با ۰
مقایسه کنیم:
alert( null > 0 ); // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true
از نظر ریاضی، این نتایج عجیب به نظر میرسد. نتیجهی آخر میگوید که null
بزرگتر یا مساوی ۰
است. بنابراین یکی از دو عبارت اوّل باید true
باشد، اما هر دو false
هستند! (جل الخالق ?)
دلیلش این است که بررسی برابری ==
و عملگرهای < > >= <=
متفاوت عمل میکنند. عملگرهای مقایسهای null
را به عدد تبدیل می کنند و در نتیجه آن را به ۰
تعبیر میکنند. به همین دلیل است که نتیجه ی سوم true
می شود و اولی false
.
از طرف دیگر، عملگر ==
برای undefined
و null
به همان روشی عمل میکند که بالاتر شرح دادیم، تبدیل دیتاتایپ صورت نمیگیرد. در این حالت null
و undefined
با هم برابرند و با هیچ چیز دیگری برابر نیستند. به همین دلیل نتیجهی دوم حاصل میشود.
undefined، موجودِ یکتا و بیهمتا!
undefined
نباید با مقادیر دیگر مقایسه شود:
alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)
چرا همیشه نتیجه false
می شود؟
این نتایج را میبینیم چون:
- مقایسه های اول و دوم
false
برمی گردانند چونundefined
بهNaN
تبدیل می شود وNaN
یک مقدار ریاضی ویژه است که در هر مقایسه مقدارfalse
را ایجاد می کند. - بررسی برابری در مورد سوم
false
را برمی گرداند چونundefined
تنها باnull
وundefined
برابر است و نه هیچ مقدار دیگری.
فرار از این مشکلات
چرا این مثال ها را ذکر کردیم؟ آیا باید این ویژگی های جاوااسکریپت را همیشه به خاطر داشته باشیم؟! پاسخ منفی است. در واقع این نکات به تدریج برایمان عادی می شود و با آنها خو می گیریم. اما راهی هم برای فرار از این مشکلات وجود دارد:
مقایسه های < > <= >=
را برای مقادیری که ممکن است null/undefined
باشند به کار نبرید، مگر آنکه دقیقا بدانید چه کاری دارید انجام می دهید. اگر یک متغیر ممکن است دارای این مقادیر باشد جداگانه آنها را بررسی کنید.