تفاوت عملگرها
برای عملیات x === y
یا Strict Equality Comparison جاوااسکریپت از الگوریتم زیر استفاده میکند: (الگوریتم ساده شده)
- اگر نوع داده ها یکسان نباشد ->
false
- اگر نوع داده ها
primitive
باشد برابر بودن مقادیر آنها مقایسه می شود
- اگر نوع داده ها
non-primitive
باشد برابر بودن در صورتی برابر هستند که به یک شی اشاره کنند.
ولی عملگر ==
یا Abstract Equality Comparison عملگر پیچیده تری است و برای مقایسه جاوااسکریپت از type coercion استفاده میکند.
یعنی برای محاسبه بر روی دو نوع داده مختلف با تبدیل کردن نوع داده سعی بر ایجاد تساوی دارد.
که این باعث به وجود آمدن باور غلط "این عملایت بدون در نظر گرفتن نوع داده فقط مقادیر را فقط بررسی میکند." شده است.
برای محاسبه x == y
جاوااسکریپت از الگوریتم زیر استفاده می شود: (الگوریتم ساده شده)
- اگر نوع داده ها یکسان باشد:
- اگر
number
باشند:
- اگر یکی از عملوندها
NaN
باشد -> false
- اگر مقدار یکسان داشته باشند ->
true
- اگر یکی
-0
و دیگری +0
باشد -> true
- در غیر این صورت ->
false
- اگر
string
باشند:
- اگر همه ی کارکترها یکسان باشند ->
true
- در غیر این صورت ->
false
- اگر
boolean
باشند
- اگر یکسان باشند ->
true
- در غیر این صورت ->
false
- اگر یکی
undefined
و دیگری null
باشد -> true
- اگر یکی
number
باشد و دیگری string
باشد انگاه رشته را به عدد تبدیل کن و عملیات را تکرار کن
- اگر نوع یکی از داده ها
boolean
باشد آنگاه آن را به عدد تبدیل کن و عملیات را تکرار کن
- اگر نوع یکی از داده ها
string
یا number
باشد و دیگری object
باشد انگاه object
را به primitive
تبدیل کن و عملیات را تکرار کن
- در غیر این صورت ->
false
چرا استفاده از عملگر == توصیه نمی شود
خوب با توجه به توضیحات بالا میتوانید متوجه شوید که عملیات == خیلی غیر قابل پیشبینی می باشد و هیچنین از قانون تراگذری نیز پیروی نمی کند و این ممکنه باعث به وجود آمدن رفتاری غیر قابل پیشبینی در کد شما شود برای مثال:
// عدم وجود رابطه تراگذری
0 == "0" // => true
0 == "" // => true
0 == "0" // => false
از دیگر مشکلات این عملگر میتوان به عدم صراحت و سخت کردن دیباگ برنامه اشاره کرد برای مثال:
function whatIsNum(a) {
if (this.num == 0){
return "?";
}
}
در مثال بالا متغیر this.num
پس از گذشتن از شرط میتواند مقادیر (0
, "0"
, []
, false
و...) را داشته باشد و این ممکن است باعث ایجاد رفتاری شود که شما انتظار ندارید.
برای همین استفاده از این عملگر جز Bad Practice ها در جاوااسکریپت است.
استفاده از این عملگر چه زمانی مناسب است؟
با توجه به مشکلاتی که ذکر شد این عملگر میتواند کاربردی باشد. یکی از کاربرد های این عملگر برای چک کردن null
یا undefined
بودن یک متغییر می باشد. برای مثال
if(a === undefined || a === null) {
// a is undefined or null
}
را میتوان به سادگی با استفاده از عملگر ==
به این صورت نوشت:
if(a == null) {
// a is undefined or null
}
۲ قطعه کد بالا کاملا یکسان هستند.
برای مطالعه بیشتر منابع زیر را پیشنهاد میکنم: