ProGraphs
822 subscribers
216 photos
6 videos
11 files
377 links
مجموعه مطالبی از برنامه‌نویسی وب و گرافیک

ProGraphs = Programming + Graphics
Download Telegram
تبدیل نوع داده‌ها (coercion) در جاوااسکریپت (قسمت چهارم):

در مطالب قبلی تبدیل نوع داده‌های مختلف به Number و String را بررسی کردیم.

حالا می‌خواهیم ساده‌ترین تبدیل، یعنی تبدیل به Boolean را بررسی کنیم:
در spec اکمااسکریپت، لیست کوتاهی از مقادیر، تحت عنوان falsy values تعریف شده است. اگر هر کدام از مقادیری که در این لیست هستند را به Boolean تبدیل کنیم، نتیجه مقدار false خواهد بود.
این لیست شامل مقادیر زیر می‌شود:
- false
- NaN
- 0
- ""
- undefined
- null
طبیعتا هر مقداری که داخل این لیست نباشد، به مقدار true تبدیل می‌شود.
در نتیجه آبجکت‌ها و آرایه‌های خالی هم به true تبدیل می‌شوند:
Boolean({}) // true
!![] // true

#quicktip #js #coercion

@ProGraphs
با اجرای این کد چه مقداری در کنسول چاپ می‌شود؟

#interviewquestion #js

@ProGraphs
با اجرای این کد چه مقداری در کنسول چاپ می‌شود؟

#interviewquestion #js

@ProGraphs
تبدیل نوع داده‌ها (coercion) در جاوااسکریپت (قسمت پنجم):

در مطالب قبلی تبدیل انواع داده‌ها به string, number, boolean و همچنین تبدیل آبجکت به primitive را بررسی کردیم. و دیدیم که هر کدام از این تبدیل‌ها از قوانین مشخصی تبعیت می‌کنند.

اما چطور می‌توانیم این تبدیل‌ها را در عمل انجام دهیم؟
تبدیل بین نوع داده‌ها به دو صورت کلی اتفاق می‌افتد:

1- explicit coercion:
در این حالت به صورت مستقیم نوع داده را تغییر می‌دهیم و با دیدن کد، واضح است که می‌خواهیم نوع داده را تغییر دهیم:
Number("40"); // explicitly coerce to number

2- implicit coercion
به دلیل ذات داینامیک جاوااسکریپت، بعضی مواقع در نتیجه‌ی انجام یک عملیات خاص، به صورت خودکار coercion اتفاق می‌افتد.
مثلا در این کد برای انجام عملیات تفریق،‌ به صورت خودکار string به عدد تبدیل می‌شود:
"20" - 5; // 15

دقت کنید که در هر دو حالت، تبدیل‌ها از قوانینی که در مطالب قبلی بررسی کردیم تبعیت می‌کنند.
در مطالب بعدی، به صورت کامل قوانین implicit coercion و explicit coercion را بررسی می‌کنیم.

#quicktip #js #coercion

@ProGraphs
تبدیل نوع داده‌ها (coercion) در جاوااسکریپت (قسمت ششم):

در مطالب قبلی نحوه‌ی تبدیل نوع داده‌های مختلف به یکدیگر را بررسی کردیم. حالا می‌خواهیم ببینیم چه زمانی این تبدیل‌ها انجام می‌شوند.
یکی از مهم‌ترین عملیات در جاوااسکریپت که باعث implicit coercion می‌شود، عملیات جمع است!

عملگر + در جاوااسکریپت، دو کار متفاوت انجام می‌دهد: جمع کردن اعداد و concat کردن stringها.

❗️اما عملگر + چطور تشخیص می‌دهد که باید عملیات جمع را انجام دهد یا concat؟
a + b
1- اگر هردو متغیر a و b از نوع string باشند، عملیات concat اتفاق می‌افتد:
"hello" + "world"; // "helloworld

2- اگر یکی از این دو متغیر از نوع string باشد، متغیر دیگر هم به string تبدیل می‌شود و دو string با هم concat می‌شوند:
1 + "20"; // "120"

3- اگر هر دو متغیر از نوع string نباشند (و آبجکت هم نباشند)، ابتدا هر دو متغیر به عدد تبدیل می‌شوند و سپس عملیات جمع اتفاق می‌افتد:
1 + true; // 2

4- اگر یک یا هردو مقدار از نوع آبجکت باشند، باید ابتدا به primitive تبدیل شوند. حالا با توجه به اینکه آبجکت‌ها به string تبدیل شده‌اند یا نه، طبق 3 قانون بالا تعیین می‌کنیم که جمع اتفاق می‌افتد یا concat.

این 4 قانون را می‌توانیم در این جمله خلاصه کنیم:
❗️اگر یکی از دو مقدار از نوع string باشد، یا حتی آبجکتی باشد که بتواند به string تبدیل شود، عملیات concat اتفاق می‌افتد. در غیر این صورت عملیات جمع اتفاق می‌افتد.

❗️اما بیاید یک بار دیگر این چهار قانون را مرور کنیم و این بار تبدیل‌هایی که به صورت خودکار بین نوع داده‌ها اتفاق می‌افتد را بررسی کنیم:
‌1- در قانون یک، coercion اتفاق نمی‌افتد!
2- در قانون دو، یکی از دو مقدار از نوع string هست. و مقدار دیگر هم به صورت خودکار به string تبدیل می‌شود.
3- در قانون سه، اگر هر کدام از دو مقدار از نوع عدد نباشند، به صورت خودکار به عدد تبدیل می‌شوند.
4- در قانون چهار آبجکت‌ها به صورت خودکار به primitive تبدیل می‌شوند.

(اگر می‌پرسید "چطور" این تبدیل‌ها اتفاق می‌افتد؟، 5 مطلب قبلی راجع به coercion رو مطالعه کنید 😁)

#quicktip #js #coercion

@ProGraphs
با اجرا کردن این دو خط کد به صورت مستقیم در کنسول مرورگر، متوجه می‌شویم که خروجی آن‌ها دو مقدار متفاوت است!
دلیل این موضوع را توضیح دهید

#interviewquestion #js

@ProGraphs
​​​​تبدیل نوع داده‌ها (coercion) در جاوااسکریپت (قسمت هفتم):

یکی دیگر از عملگرهایی که باعث می‌شود نوع داده‌ها به صورت خودکار تغییر کنند، عملگر مقایسه‌ای ">" است.
این عملگر می‌تواند به دو صورت مختلف مقایسه را انجام دهد:
1- مقایسه‌ی ریاضی:
1 < 2; // true

2- مقایسه‌ی alphabetic:
"aa" < "ab"; // true
"1" < "02"; // false
همانطور که می‌بینید در این حالت تک تک حروف string به صورت alphabetic مقایسه می‌شوند. یعنی 'a' از 'b' کوچک‌تر است.

❗️اما عملگر ">" چطور تشخیص می‌دهد که به کدام روش مقایسه را انجام دهد و چه زمانی نوع داده‌ها را تغییر می‌دهد (implicit coercion)؟
طبق spec اکمااسکریپت، این عملگر برای انجام مقایسه این مراحل را طی می‌کند:

1- برای انجام مقایسه هر دو مقدار باید primitive باشند. بنابراین اگر مقادیری که مقایسه می‌شوند از نوع آبجکت باشد، باید به primitive تبدیل شود (به مطلبی که راجع به تبدیل آبجکت به primitive منتشر کردیم مراجعه کنید)

2- حالا که مطمئنیم هر دو مقدار primitive هستند، اگر هر دو مقدار string باشند، مقایسه به صورت alphabetic انجام می‌شود.

3- اگر حتی یکی از دو مقدار از نوع string نباشد، هر دو مقدار به صورت خودکار به عدد تبدیل می‌شوند و مقایسه‌ی عددی انجام می‌شود (به کد داخل تصویر دقت کنید).

#quicktip #js #coercion

@ProGraphs
با اجرای این کد چه مقادیری در کنسول چاپ می‌شود؟
(به ترتیب از چپ به راست)

#interviewquestion #js

@ProGraphs
​تبدیل نوع داده‌ها (coercion) در جاوااسکریپت (قسمت هشتم):

در انتهای مطالب coercion، عملگر "==" را بررسی می‌کنیم. همانطور که در مطالب قبلی دیدیم، اگر دو مقداری که با استفاده از عملگر "==" مقایسه می‌کنیم، از یک نوع داده نباشند، به صورت خودکار نوع داده‌ی مقادیر تغییر می‌کند تا مقایسه بین دو مقدار با نوع داده‌ی یکسان انجام شود.

❗️این موضوع در بعضی موارد نتایج کاملا گیج کننده‌ای را رقم می‌زند.
برای مثال:
20 == true; // false

در این کد یک مقدار از نوع boolean است و مقدار دیگر از نوع عدد. طبیعتاً انتظار داریم عدد 20، به مقدار true تبدیل شود و نتیجه‌ی مقایسه true شود.

اما با مراجعه به spec اکمااسکریپت، متوجه می‌شویم که اگر یک مقدار دیگر را با true یا false مقایسه کنیم، به جای اینکه مقدار مورد نظر به boolean تبدیل شود، مقدار boolean به عدد تبدیل می‌شود!
پس در این کد ابتدا مقدار true به عدد 1 تبدیل می‌شود و سپس عدد 1 و 20 مقایسه می‌شوند و نتیجه‌ی مقایسه false می‌شود.

❗️اما گاهی این کارکرد عملگر "=="، منطقی و مفید است.
برای مثال:
null == undefined; // true
همانطور که در این کد می‌بینید، وقتی با استفاده از عملگر "==" مقایسه را انجام می‌دهیم، دو مقدار null و undefined می‌توانند به یکدیگر تبدیل شوند.
به این ترتیب لازم نیست برابر بودن یک مقدار را هم با null و هم با undefined چک کنیم (به کد داخل تصویر دقت کنید)

#quicktip #js #coercion

@ProGraphs
با اجرای این کد چه مقداری در کنسول چاپ می‌شود؟

#interviewquestion #js

@ProGraphs
یک کاربرد جالب spread operator برای اضافه کردن یک آیتم به آرایه/آبجکت به صورت شرطی.

#quicktip #js #trick

@ProGraphs
فرض کنید همچین تابعی را در جاوااسکریپت نوشته‌ایم که با استفاده از transitionهای css، یک عنصر را از یک موقعیت به یک موقعیت دیگر جابه‌جا کند.

اما با اجرا شدن این تابع متوجه می‌شویم که موقعیت اولیه‌ای که برای عنصر تعریف می‌کنیم (خط ۲) کاملا نادیده گرفته می‌شود و عنصر بدون توجه به موقعیت اولیه، فقط به سمت موقعیت نهایی جابه‌جا می‌شود!

علت این موضوع چیست؟ شما چطور این مشکل را حل می‌کنید؟

#interviewquestion #js #css

@ProGraphs
در این کد برای event کلیک یک عنصر، دو listener تعریف کرده‌ایم.

با کلیک کردن بر روی این عنصر، چه مقادیری در کنسول چاپ می‌شوند؟
(به ترتیب از چپ به راست)

#interviewquestion #js #async

@ProGraphs
همه‌ی ما strict-mode را به عنوان یک ویژگی برای محدود کردن بعضی رفتارهای نامتعارف جاوااسکریپت می‌شناسیم.
اما فواید strict-mode فقط به اینجا ختم نمی‌شود.
❗️در واقع محدودیت‌های بیشتری که تو این حالت اعمال می‌شود، به انجین جاوااسکریپت اجازه می‌دهد که بهینه‌سازی‌های بیشتری هم روی کد انجام دهد.

به عنوان مثال در یکی از مطالب قدیمی‌تر، با wrapper objectها آشنا شدیم.
❗️و دیدیم که به لطف wrapper objectها، داده‌های primitive هم می‌توانند مثل آبجکت‌ها متد داشته باشند.
یعنی در کد زیر، جاوااسکریپت به صورت خودکار string را تبدیل به یک wrapper object می‌کند تا متد trim را روی آن صدا کند:
"some string".trim()

❗️اما جالبه بدونید که تو حالت strict-mode، وقتی از یکی از متدهای اعداد یا stringها استفاده می‌کنیم، انجین جاوااسکریپت یک wrapper object اضافه نمی‌سازد و مستقیما از متدی که داخل prototype تعریف شده استفاده می‌کند!

برای اثبات این موضوع به کد داخل تصویر دقت کنید.
می‌بینید که متد دوم که در حالت strict-mode اجرا میشود، هیچ آبجکت اضافه‌ای برای box کردن string نمی‌سازد.

#quicktip #js #optimization

@ProGraphs
به کد زیر دقت کنید:
let obj = {
whatIsThis: () => {
console.log("this is:", this);
}
};
در این کد، متد whatIsThis داخل آبجکت obj تعریف شده است. اما با توجه به اینکه arrow functionها در جاوااسکریپت this ندارند، مقدار this داخل این تابع به آبجکت گلوبال اشاره می‌کند (و نه به خود آبجکت obj).

اما چرا وقتی از arrow functionها در کلاس‌های جاوااسکریپت استفاده می‌کنیم، مقدار this به خود آبجکت‌های کلاس اشاره می‌کند؟
به عنوان مثال به کد داخل تصویر (که یک کلاس کامپوننت ری‌اکت است) دقت کنید.
متد handleClick را به صورت arrow function تعریف کرده‌ایم، اما مقدار this به خود آبجکت react element اشاره می‌کند! (دقیقا برعکس رفتاری که در کد بالا دیدیم)

چرا رفتار arrow functionها در آبجکت‌ها و class field‌های جاوااسکریپت متفاوت است؟

#interviewquestion #js #react #thiskeyword

@ProGraphs
توی این کد سعی میکنیم درخواستی به سرور بفرستیم و اگر درخواست fail شد، بعد از 100ms دوباره این کار رو تکرار میکنیم.

اما بعد از اجرا شدن این پروسه به مدت طولانی، متوجه memory leak میشیم.
آیا میتونید این مشکل رو پیدا و حل کنید؟
(عکس ویرایش شد)

#question #js #promise #memoryleak

@ProGraphs