Truthy، Falsy و روشهای مقایسهی مقادیر
اهداف یادگیری
- مرور و تثبیت مفهوم Truthy و Falsy در شرطها
- درک تفاوت دقیق بین
==و=== - آشنایی با
Object.isو تفاوت آن با=== - توانایی انتخاب روش مناسب مقایسه در موقعیتهای مختلف
مقدمه
در درس قبل با مفهوم Truthy و Falsy آشنا شدیم. در این درس، این مفهوم را کاملتر بررسی میکنیم و سپس وارد یکی از مهمترین مباحث جاوااسکریپت میشویم: تفاوت بین == و ===. این تفاوت مستقیماً به Type Coercion که در درس قبل یاد گرفتیم مرتبط است.
مرور Truthy و Falsy
همانطور که در درس قبل دیدیم، جاوااسکریپت در شرطها هر مقداری را به Boolean تبدیل میکند. فقط شش مقدار زیر Falsy هستند:
false
0
""
null
undefined
NaN
هر مقدار دیگری، از جمله آرایهی خالی [] و شیء خالی {}، Truthy محسوب میشود:
if ([]) {
console.log("اجرا میشود"); // چون [] یک مقدار Truthy است
}
if ({}) {
console.log("این هم اجرا میشود"); // چون {} هم Truthy است
}
عملگر == (Loose Equality)
عملگر == پیش از مقایسه، در صورت متفاوت بودن نوع دو مقدار، ابتدا آنها را با قوانین Type Coercion به یک نوع مشترک تبدیل میکند و سپس مقایسه انجام میشود:
console.log(5 == "5"); // true — رشته به عدد تبدیل میشود
console.log(0 == false); // true — false به 0 تبدیل میشود
console.log(null == undefined); // true — قاعدهی خاص برای این دو
console.log("" == 0); // true — رشتهی خالی به 0 تبدیل میشود
همین رفتار باعث میشود == گاهی نتایج غیرمنتظره و دشوار برای پیشبینی تولید کند.
عملگر === (Strict Equality)
عملگر === هیچگونه تبدیل نوعی انجام نمیدهد. اگر نوع دو مقدار یکسان نباشد، بلافاصله false برمیگرداند:
console.log(5 === "5"); // false — نوع متفاوت است
console.log(0 === false); // false — نوع متفاوت است
console.log(5 === 5); // true — نوع و مقدار یکسان است
تحلیل کد
تفاوت اصلی این دو عملگر در این است که == ابتدا سعی میکند دو مقدار را «قابل مقایسه» کند، اما === از همان ابتدا هم نوع و هم مقدار را باهم میسنجد. به همین دلیل، === رفتاری کاملاً قابل پیشبینی دارد و == وابسته به قوانین پیچیدهی Type Coercion است.
Object.is چیست؟
Object.is شبیه به === عمل میکند، اما در دو مورد خاص رفتار متفاوتی دارد:
console.log(Object.is(NaN, NaN)); // true
console.log(NaN === NaN); // false
console.log(Object.is(0, -0)); // false
console.log(0 === -0); // true
در جاوااسکریپت، NaN با هیچ مقداری، حتی خودش، با === برابر نیست. اما Object.is این استثنا را در نظر میگیرد و NaN را با خودش برابر میداند. از سوی دیگر، 0 و -0 با === برابر شناخته میشوند، اما Object.is بین آنها تفاوت قائل میشود.
جدول مقایسه
| عملگر | تبدیل نوع؟ | NaN با NaN | 0 با -0 |
|---|---|---|---|
== | بله | false | true |
=== | خیر | false | true |
Object.is | خیر | true | false |
اشتباهات رایج
- استفادهی گسترده از
==بدون آگاهی از قوانین Type Coercion، که میتواند باگهای پنهان ایجاد کند. - استفاده از
===برای بررسی برابر بودن یک مقدار باNaN؛ در حالی که راه درست استفاده ازNumber.isNaN()یاObject.isاست. - تصور اینکه
Object.isجایگزین کاملی برای===در همهی موارد است؛ درحالیکه تفاوت آنها فقط در دو مورد خاص (NaN و ۰/-۰) بروز میکند.
Best Practices
- همیشه از
===بهجای==استفاده کنید، مگر در موارد بسیار خاص که مقایسهیnullوundefinedبا هم مدنظر باشد. - برای بررسی NaN از
Number.isNaN(value)استفاده کنید، نه از مقایسهی مستقیم.
ارتباط با سایر مفاهیم
مفهوم Truthy/Falsy مستقیماً روی رفتار ساختارهای شرطی مثل if تأثیر میگذارد، و تفاوت == و === در واقع کاربرد عملی همان قوانین Type Coercion است که در درس قبل بررسی کردیم. این مفاهیم در فصلهای آینده، بهویژه در تحلیل رفتار کد و پیشبینی خروجی، بارها مورد استفاده قرار میگیرند.
جمعبندی
عملگر == پیش از مقایسه، مقادیر را با قوانین Type Coercion همنوع میکند، درحالیکه === بدون هیچ تبدیلی، نوع و مقدار را دقیقاً مقایسه میکند. Object.is نیز مشابه === عمل میکند، با دو استثنای مهم: NaN را با خودش برابر میداند و بین 0 و -0 تفاوت قائل میشود.
