مقایسه ها توی ریاضیات چیزای آشنایی هستن، درسته؟ توی جاوااسکریپت هم همون مفاهیم رو داریم، اما با یه شکل و شمایل خاص.
گاهی وقتا می خوایم یه تست درست/غلط انجام بدیم و بسته به نتیجش یه کاری انجام بدیم. اینجاست که عملگرهای مقایسه به کارمون میان.
بیایید عملگرهای مقایسه رو با مثال و توضیح ساده یاد بگیریم:
| عملگر | اسم | کاربرد | مثال |
|---|---|---|---|
=== | مساویِ سختگیرانه | چک می کنه که مقدار سمت چپ و راست دقیقاً شبیه همدیگه باشن (هم مقدار، هم نوع داده). | 5 === 2 + 4 (غلطه!) |
!== | نامساوی سختگیرانه | چک می کنه که مقدار سمت چپ و راست دقیقاً شبیه همدیگه نباشن. | 5 !== 2 + 3 (غلطه!) |
< | کوچک تر از | چک می کنه که مقدار سمت چپ از مقدار سمت راست کوچیک تر باشه. | 10 < 6 (غلطه!) |
> | بزرگ تر از | چک می کنه که مقدار سمت چپ از مقدار سمت راست بزرگ تر باشه. | 10 > 20 (غلطه!) |
<= | کوچک تر یا مساوی | چک می کنه که مقدار سمت چپ کوچیک تر یا برابر مقدار سمت راست باشه. | 3 <= 2 (غلطه!) |
>= | بزرگ تر یا مساوی | چک می کنه که مقدار سمت چپ بزرگ تر یا برابر مقدار سمت راست باشه. | 5 >= 4 (درسته!) |
[note]
یه نکته مهم! بعضی جاها ممکنه از == و != هم برای مقایسه استفاده بشه. اینا عملگرهای معتبر توی جاوااسکریپت هستن، ولی با نسخه های سختگیرانه تر یعنی === و !== یه تفاوت مهم دارن:
مثال:
5 == "5"; // درسته، چون فقط مقدارها رو چک می کنه.
5 === "5"; // غلطه، چون نوع داده ها فرق دارن (یکی عدد، یکی رشته).توصیه ی دوستانه: استفاده از نسخه های سختگیرانه تر (=== و !==) معمولاً باعث می شه کدت کم تر خطا بده و رفتار غیرمنتظره نداشته باشه. پس بهتره همیشه از اونا استفاده کنی! 😎
[/note]
توی کنسول جاوااسکریپت اگر مقادیر مختلفی رو امتحان کنی، می بینی که همه شون به یه مقدار true یا false تبدیل می شن. این مقادیر همون Booleanهایی هستن که تو مقالات قبلی یاد گرفتیم.
حالا چرا اینقدر بولین ها مهمن؟ چون به ما اجازه می دن توی کدمون تصمیم بگیریم که چی کار کنیم. وقتی می خوایم یه انتخاب انجام بدیم، بولین ها حکم چراغ سبز و قرمز رو دارن! چند تا مثال ساده:
برای مثال:
alert(2 > 1); // true (درسته)
alert(2 == 1); // false (اشتباهه)
alert(2 != 1); // true (درسته)جالب اینجاست که می تونی نتیجه مقایسه رو توی یه متغیر ذخیره کنی، درست مثل هر مقدار دیگه ای:
let result = 5 > 4; // نتیجه مقایسه توی متغیر ذخیره می شه
alert(result); // trueحالا با یه مثال ساده ببینیم که چجوری می تونیم با استفاده از منطق بولین و مقایسه، رفتار دکمه ای که متنش تغییر می کنه رو کنترل کنیم.
کد HTML:
<button>Start machine</button>
<p>The machine is stopped.</p>این کد ساده ی HTML دو بخش داره:
کد جاوااسکریپت:
const btn = document.querySelector("button");
const txt = document.querySelector("p");
btn.addEventListener("click", updateBtn);
function updateBtn() {
if (btn.textContent === "Start machine") {
btn.textContent = "Stop machine";
txt.textContent = "The machine has started!";
} else {
btn.textContent = "Start machine";
txt.textContent = "The machine is stopped.";
}
}توضیح کد:
اگه متن دکمه "Start machine" باشه:
متن دکمه رو به "Stop machine" تغییر بده.
وضعیت ماشین رو توی پاراگراف بنویس: "The machine has started!".
اگه متن دکمه چیز دیگه ای باشه:
متن دکمه رو برگردون به "Start machine".
وضعیت رو بنویس: "The machine is stopped.".
نتیجه:
با هر بار کلیک روی دکمه:
توی تابع updateBtn() از عملگر مقایسه ای == استفاده کردیم. اما اینجا دیگه هدفمون مقایسه دو تا عدد نیست. در واقع داریم چک می کنیم که متن دکمه برابر با یه رشته خاص هست یا نه. اگه متن دکمه "Start machine" باشه، متن رو به "Stop machine" تغییر می دیم و وضعیت ماشین رو هم آپدیت می کنیم. اما اگه متن دکمه "Stop machine" باشه، برعکس عمل می کنیم و برمی گردیم به حالت اول.
نکته: به این نوع کنترل ها که بین دو حالت جا به جا می شن، Toggle می گن. مثل کلید چراغ که وقتی فشارش می دی، یا چراغ رو روشن می کنه یا خاموش. توی کدنویسی هم چنین رفتارهایی خیلی رایج و کاربردی هستن.
🎉زنگ تفریح: اصلا بیا واقعا یه لامپ وصل کنیم و روشن خاموشش کنیم: 😉
تو این مثال، با استفاده از جاوااسکریپت می تونیم مقدار یکی از ویژگی های (attributes) یک عنصر HTML رو تغییر بدیم. اینجا، با کلیک روی دکمه ها، تصویر لامپ تغییر می کنه و روشن یا خاموش می شه.
<!DOCTYPE html>
<html>
<body>
<h2>What Can JavaScript Do?</h2>
<p>JavaScript can change HTML attribute values.</p>
<p>In this case JavaScript changes the value of the src (source) attribute of an image.</p>
<button onclick="document.getElementById('myImage').src='pic_bulbon.gif'">Turn on the light</button>
<img id="myImage" src="pic_bulboff.gif" style="width:100px">
<button onclick="document.getElementById('myImage').src='pic_bulboff.gif'">Turn off the light</button>
</body>
</html>توضیحات کد:
یک تصویر با id="myImage" داریم که پیش فرض به صورت لامپ خاموش (تصویر pic_bulboff.gif) نمایش داده می شه.
دو دکمه داریم: یکی برای روشن کردن لامپ و دیگری برای خاموش کردنش.
وقتی روی دکمه Turn on the light کلیک می کنی، تابع onclick اجرا می شه.
تابع onclick به ویژگی src تصویر، مقدار جدیدی می ده: pic_bulbon.gif، که تصویر لامپ روشنه.
به طور مشابه، وقتی روی دکمه Turn off the light کلیک می کنی، ویژگی src دوباره به مقدار pic_bulboff.gif برمی گرده، که لامپ رو خاموش نشون می ده.
هر بار که یکی از دکمه ها رو فشار بدی، تصویر تغییر می کنه. این تعامل نشون می ده که چطور می شه با جاوااسکریپت به راحتی مقادیر ویژگی های یک عنصر رو تغییر داد.
نکته: برای دیدن نتیجه، باید فایل HTML رو توی مرورگر باز کنی و مطمئن بشی که تصاویر (pic_bulbon.gif و pic_bulboff.gif) در همون پوشه ای که فایل HTML ذخیره شده، موجود باشن.
نکته مهم: اگه با دیدن این مثال برات سوال پیش اومده که جاوااسکریپت چطور این کارو انجام داده، نگران نباش! 😊
تو این مرحله ممکنه هنوز با مفهوم هایی مثل رویدادها (events) و دستکاری عناصر HTML (DOM manipulation) آشنا نباشی، اما این طبیعیه. این مثال فقط برای نشون دادن قدرت جاوااسکریپت و جذابیتش آورده شده.
برای اینکه الان بیشتر درکش کنی، می تونی درباره ی موارد زیر یه سرچ کوچولو انجام بدی:
و اگر هم حوصله نداری که الان تحقیق کنی، اصلاً مشکلی نیست. توی مقالات بعدی دقیقاً همین موضوع ها رو با هم یاد می گیریم و می فهمیم که این کد چطور کار می کنه.
برای اینکه ببینیم یه رشته از یه رشته دیگه بزرگ تره یا نه، جاوااسکریپت از یه ترتیب به اسم "ترتیب دیکشنری" یا "ترتیب لغت نامه ای" استفاده می کنه. یعنی حروف رو یکی یکی و به ترتیب با هم مقایسه می کنه.
مثال ها:
alert('Z' > 'A'); // true
alert('Glow' > 'Glee'); // true
alert('Bee' > 'Be'); // trueالگوریتم مقایسه رشته ها:
1. اولین حرف هر دو رشته رو با هم مقایسه می کنه.
2. اگه اولین حرف رشته اول بزرگ تر (یا کوچک تر) از حرف رشته دوم باشه، نتیجه مقایسه مشخصه.
3. اگه حرف های اول برابر باشن، میره سراغ حرف دوم و همین روند ادامه پیدا می کنه.
4. اگه همه حروف برابر بودن ولی طول رشته ها فرق داشت، رشته بلندتر بزرگ تر حساب می شه.
برای مثال:
G با G برابرن.
l با l برابرن.
o از e بزرگ تره. پس 'Glow' بزرگ تره.
یه نکته مهم: این ترتیب لغت نامه ای کاملاً واقعی نیست
توی جاوااسکریپت، این الگوریتم بیشتر شبیه ترتیب لغت نامه ایه، ولی دقیقاً همون نیست. چرا؟ چون یونی کُد (Unicode) رو ملاک قرار می ده.
توی یونی کُد، حروف کوچک از حروف بزرگ بزرگ ترن. مثلاً:
alert('a' > 'A'); // trueپس 'a' به خاطر اینکه توی جدول یونی کُد شاخص بالاتری داره، از 'A' بزرگ تر حساب می شه. جزئیات بیشتر این موضوع رو توی مقاله مربوط به رشته ها بررسی می کنیم.
وقتی تو جاوااسکریپت مقادیر از انواع مختلف رو با هم مقایسه می کنی، جاوااسکریپت معمولاً اول مقادیر رو به عدد تبدیل می کنه.
مثال هایی ساده:
برای مقادیر بولین هم:
مثال های بولین:
گاهی پیش میاد که:
مثال:
let a = 0;
alert(Boolean(a)); // false، چون عدد صفر به false تبدیل می شه
let b = "0";
alert(Boolean(b)); // true، چون رشته غیرخالی همیشه true می شه
alert(a == b); // true، چون جاوااسکریپت برای مقایسه اون ها رو به عدد تبدیل می کنهچرا اینطوریه؟
این رفتار جاوااسکریپت گاهی می تونه گیج کننده باشه. برای جلوگیری از این سردرگمی، بهتره همیشه از عملگرهای برابر دقیق (===) استفاده کنی که هم نوع داده و هم مقدارشون رو بررسی می کنن.
تو جاوااسکریپت، یه مشکل جالب با عملگر برابری معمولی == هست: این عملگر نمی تونه فرق بین 0 و false رو بفهمه.
مثال های واضح:
alert(0 == false); // true
alert('' == false); // trueچرا این اتفاق میوفته؟
چون وقتی از == استفاده می کنی، جاوااسکریپت سعی می کنه مقادیر رو به عدد تبدیل کنه. مثلاً:
پس نتیجه می شه 0 == 0 و برابر در نظر گرفته می شن.
اگه بخوایم بدون تبدیل نوع مقایسه کنیم و فرق بین 0 و false رو تشخیص بدیم، باید از برابر دقیق (===) استفاده کنیم.
عملگر === فقط وقتی true برمی گردونه که:
مثال:
alert(0 === false); // false، چون نوع داده ها متفاوته
alert('' === false); // false، باز هم به خاطر نوع داده متفاوتبرای مقایسه نابرابر هم نسخه دقیق داریم: !==
این دقیقاً شبیه به != هست، ولی بدون تبدیل نوع.
هرچند نوشتن === یه کوچولو طولانی تره، ولی کاملاً مشخص می کنه که چی کار داریم می کنیم و از خطاهای عجیب جلوگیری می کنه. پس پیشنهاد می کنم همیشه از برابر دقیق (===) استفاده کنی.
وقتی پای null و undefined به مقایسه باز می شه، رفتار جاوااسکریپت یه ذره عجیب و غریب می شه. بیایید با هم بررسی کنیم.
گفتیم اگر از === استفاده کنیم هم مقدار و هم نوع داده با هم مقایسه می شن. اگه بخوایم از برابر دقیق (===) استفاده کنیم.
alert(null === undefined); // falseاینجا null و undefined برابر نیستن چون نوع داده هاشون فرق داره.
اینجا یه قانون خاص وجود داره:
null و undefined فقط با هم برابر هستن و با هیچ مقدار دیگه ای برابر نمی شن.
alert(null == undefined); // trueوقتی null وارد مقایسه ریاضی بشه (<, >, <=, >=):
وقتی undefined وارد مقایسه ریاضی بشه:
مثال:
alert(null > 0); // false (چون null به 0 تبدیل می شه، اما جاوااسکریپت می گه 0 > 0 درست نیست)
alert(null == 0); // false (چون null فقط با undefined برابره، نه چیز دیگه)
alert(null >= 0); // true (چون null به 0 تبدیل می شه، و 0 >= 0 درست هست)چرا این اتفاق میوفته؟
جاوااسکریپت برای مقایسه ها از قوانین خاص خودش استفاده می کنه:
null → 0
undefined → NaN
| عملگر | null | undefined |
|---|---|---|
| === | فقط با خودش برابر است | فقط با خودش برابر است |
| == | با undefined برابر است | با null برابر است |
| <, >, <=, >= | به 0 تبدیل می شود | به NaN تبدیل می شود |
حواست باشه این رفتار جاوااسکریپت گاهی می تونه تله باشه، ولی با تمرین و درک دقیق، این مشکلات رو راحت مدیریت می کنی.
تمرین 1:
alert(undefined == null); // ?
alert(undefined === null); // ?جواب:
true برای اولی، چون با == این دو برابر هستن.
false برای دومی، چون نوع داده هاشون فرق داره.
تمرین 2:
alert(null > 0); // ?
alert(null == 0); // ?
alert(null >= 0); // ?جواب: false, false, true.
تمرین 3:
alert(undefined > 0); // ?
alert(undefined == 0); // ?
alert(undefined >= 0); // ?جواب: همه ی مقایسه ها false می شن، چون undefined توی مقایسه ریاضی به NaN تبدیل می شه.
undefined با هیچ مقداری کنار نمیاد و وقتی باهاش مقایسه می کنی، معمولاً جواب ها خیلی عجیبه:
alert(undefined > 0); // false (1)
alert(undefined < 0); // false (2)
alert(undefined == 0); // false (3)خب چرا همیشه جواب false می شه؟ چه مشکلی با صفر داره؟ 🤔
مقایسه های ریاضی (>, <)
وقتی با undefined مقایسه می کنی، جاوااسکریپت سعی می کنه اون رو به عدد تبدیل کنه.
ولی وقتی undefined به عدد تبدیل می شه، مقدارش می شه NaN.
و خب، NaN توی همه مقایسه های ریاضی همیشه false برمی گردونه.
بنابراین:
alert(undefined > 0); // false
alert(undefined < 0); // falseمقایسه برابری (==)
برای ==، جاوااسکریپت اصلاً undefined رو به عدد تبدیل نمی کنه.
اینجا یه قانون خاص وجود داره:
undefined فقط با undefined و null برابره، نه با هیچ مقدار دیگه ای.
بنابراین:
alert(undefined == 0); // falseخب حالا که فهمیدیم undefined یه مقدار خاص و دردسرسازه، بهتره که موقع مقایسش با دقت عمل کنیم:
مثال:
let value;
if (value === undefined || value === null) {
alert("Value is either undefined or null");
} else if (value > 0) {
alert("Value is greater than 0");
}اینجوری خیالت راحته که مقایسه ها درست انجام می شن و رفتار غیرمنتظره ای پیش نمیاد.
5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"بیایید با هم بررسی کنیم:
5 > 4 // true
"apple" > "pineapple" // false
"2" > "12" // true
undefined == null // true
undefined === null // false
null == "\n0\n" // false
null === +"\n0\n" // falseچرا این جوری می شه؟
1. 5 > 4 → true: خب این واضحه، ۵ بزرگ تر از ۴ هست و نتیجه true می شه.
2. "apple" > "pineapple" → false: اینجا مقایسه لغت نامه ای انجام می شه. چون "a" از "p" کوچیک تره، نتیجه false می شه.
3. "2" > "12" → true
باز هم مقایسه لغت نامه ای.
جاوااسکریپت اولین کاراکتر رو بررسی می کنه:
"2" از "1" بزرگ تره، پس نتیجه true می شه.
4. undefined == null → true
توی مقایسه شُل (غیرسختگیرانه)، undefined و null فقط با خودشون برابر هستن.
اینجا جاوااسکریپت هیچ تبدیلی انجام نمی ده و نتیجه true می شه.
5. undefined === null → false: اما توی مقایسه سختگیرانه (===)، چون نوع داده ها فرق داره (یکی undefined و یکی null)، نتیجه false می شه.
6. null == "\n0\n" → false
توی مقایسه شُل، null فقط با خودش و undefined برابر هست.
اینجا چون با یه رشته مقایسه می شه، نتیجه false می شه.
7. null === +"\n0\n" → false
اینجا +"\n0\n" به عدد ۰ تبدیل می شه.
ولی چون مقایسه سختگیرانه هست و نوع داده ها متفاوتن (null و number)، نتیجه false می شه.
یادت باشه همیشه تفاوت بین == و === رو بدونی و وقتی پای null و undefined وسطه، حواست به قوانین خاصشون باشه.
اصفهان، خیابان حمزه اصفهانی، بن بست تخت جمشید(18) ، پلاک ۴
دفتر تهران: تهران، خیابان سهروردی شمالی، خیابان هویزه شرقی، پلاک 20، طبقه دوم، واحد 6