جاوااسکریپت و کارای عجیبش [قسمت اول]

خیلیا میگن جاوااسکریپت خنگه چون مثالا "41" = "1" + 4، ولی اگه بدونیم عملگر جمع، اگه یکی از طرفینش استرینگ باشه، طرف دیگه رو هم به استرینگ تبدیل میکنه بعد عمل جمع رو انجام میده دیگه بهش نمیگیم خنگ! شاید بگیم عجیب، ولی نمیگیم خنگ. خیلی از این فحش‌هایی که به جی‌اس میدیم صرفا بخاطر اینه که ابزارمونو کامل نمیشناسیم. پس بیاین باهم کمی از کارای عجیب جی‌اس رو ببینیم و بهتر بشناسیمش.قبل از هر چیزی باید تایپ‌های اصلی جاوااسکریپت رو بشناسیم. بعضیا میکن تو جاوااسکریپت تایپ همه‌چیز object‌ـه، ولی این غلطه! شاید گاهی مثل object رفتار کنن، ولی object نیستن. تایپ‌های اصلی تو جاوااسکریپت undefined, string, number, boolean, object, symbol, bigint. ولی subtype هایی هم داریم، مثل array و function که object هستن. حالا که تایپ‌های اصلیو دیدیم باید ببینیم چطوری تبدیل تایپ‌ها انجام میشه. بیاین فرض کنیم یه متد ()toPrimitive ای وجود داره که یه ورودی optional داره به اسم hint. این hint میتونه یا number باشه یا string. یعنی کار این متد اینه که یه متغیری رو به تایپ اصلیش برسونه. اگه با هینت number صدا بزنیمش اول ()valueOf رو صدا میزنه. اگه عددی باشه ()valueOf نتیجه داره، پس return میشه. اگه عددی نباشه ()toString رو صدا میزنه، اگه ()toString نتیجه بده return میشه، اگه نتیجه نده ()toPrimitive ارور میده. به همین صورت اگه هینت string باشه اول ()toString و بعدش ()valueOf صدا زده میشن.این چند خط یه ایده کلی از عملکرد تبدیل تایپ تو جاوااسکریپت بهمون میدن، حالا میتونیم یکم از عجایبش ببینیم.بیاین با toString شروع کنیم. اول بگم که از این toString منظور تمام راه های تبدیل به استرینگه toString ای که یه object میگیره و toPrimitive با هینت string رو صدا میکنه. پس عملا اول ()toString و بعدش ()valueOf رو براش صدا میزنه. اکثر موارد رو همونطوری که میشه حدث زد انجام میده، مثل لیست زیر:null &quotnull&quot undefined &quotundefined&quot true &quottrue&quot false &quotfalse&quot 3.14159 &quot3.14159&quotحالا toString ای که برای array داریم برخورد جالبی داره، میاد ارایه رو serialize میکنه، یعنی "1,2,3" = [3, 2, 1]. قسمت عجیبش تو برخورد با null و undefinedـه، یعنی "," = [null, undefined]!!! انگار تو سریالایز کردنش حذفشون میکنه!توی toNumber قسمت جالب اینه که اکثر مشکلا از یه جا شروع میشه. از اون جایی که ‌"" رو تبدیل میکنه به 0. خیلی عجیبه چون یه استرینگ خالی به معنی اینه که هیچ مقداری استرینگمون نداره، ولی 0 اصلا به این معنی نیست تو اعداد!! در نتیجه [""] تبدیل میکنه به 0. چرا؟ چون برای تبدیلش به عدد اون toPrimitive رو صدا میزنه، toPrimitive اول valueOf و بعدش toString میکنه. با توجه به اینکه valueOf برای نتیجه‌ای نداره میره toString، قسمت قبل دیدیم برای تبدیل ارایه به استرینگ سریالایز میشه و دیدیم "" تبدیل میشه به "0". نکته جالب toPrimitive اینه که به صورت بازگشتی ادامه میده تا به نیجه برسه. پس الان که toString براش "0" رو برگردوند دوباره toPrimitive اجرا میشه، toValue براش 0 رو برمیگردونه. حالا [null] و [undefined] چرا میشن 0؟ اینم باز به قسمت قبل برمیگرده، toValue نتیجه نمیده میره توی toString، دیدیم برای تبدیل ارایه به استرینگ null و undefined عملا حذف میشدن، پس [null] و [undefined] نتیجشون "" برمیگرده و همونطور که دیدیم تبدیل "" رو جاوااسکریپت تبدیل به 0 میکنه.ولی toBoolean راحت‌تر از بقیه عمل میکنه. toBoolean یه لیست داره از تمام مواردی که false محسوب میشن، هر چیزی خارج از این لیستو به true تبدیل میکنه. این لیستو ببینیم:false &quot&quot 0, -0 null undefined NaNپس عملا هر مقداری که بخواد به بولین تبدیل بشه فقط چک میشه که تو این لیست هست یا نه، اگه بود false و اگه نبود true میشه.