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

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

در مطلب قبلی، تبدیل نوع داده‌ها به string را بررسی کردیم و نحوه‌ی تبدیل آبجکت‌ها به string را هم دیدیم.

حالا می‌خواهیم نحوه‌ی تبدیل آبجکت‌ها به primitive را دقیق‌تر بررسی کنیم (نه فقط string):

❗️وقتی سعی می‌کنیم یک آبجکت را به یک نوع داده مثل number, string تبدیل کنیم (که نوع داده‌های primitive هستند)، باید ابتدا آبجکت به primitive تبدیل شود. اما چطور؟

1- اگر متدی به نام valueOf در آبجکت وجود داشته باشد و خروجی این متد از نوع primitive باشد، همین متد صدا می‌شود:
var obj = {
valueOf() {
return 2;
}
};
obj -> 2
2- اگر از مرحله‌ی قبلی مقدار primitive تعیین نشود، متد toString صدا می‌شود:
var obj = {
toString() {
return "hi";
}
};
obj -> "hi"
دقت کنید که این مراحل، توسط خود جاوااسکریپت و زمانی که می‌خواهیم یک آبجکت را به یک نوع داده‌ی primitive مثل string تبدیل کنیم انجام می‌شود.

❗️نکات تکمیلی:
- همانطور که در مطلب قبلی هم دیدیم، متدهای valueOf و toString در Object.prototype تعریف شده‌اند. بنابراین اگر خودمان این متدها را داخل یک آبجکت تعریف نکنیم، متدهای داخل Object.prototype برای تبدیل به primitive صدا می‌شوند (به مطالبی که راجع به prototype chain منتشر کردیم مراجعه کنید).

- گاهی ترتیب صدا شدن دو متد valueOf و toString برعکس چیزی است که در این مطلب دیدیم. دلیل این موضوع را در مطالب بعدی بررسی می‌کنیم. اما فعلا اهمیتی ندارد 😅

#quicktip #js

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

در مطلب قبلی نحوه‌ی تبدیل آبجکت‌ها به primitive را بررسی کردیم و دیدیم که هرگاه می‌خواهیم یک آبجکت را به یک نوع داده‌ی primitive مثل number و string تبدیل کنیم، باید ابتدا آبجکت به primitive تبدیل شود.

حالا می‌خواهیم بر پایه‌ی همین موضوع، نحوه‌ی تبدیل نوع داده‌های مختلف به Number را بررسی کنیم:
❗️تقریبا برای همه‌ی مقادیر primitive، حالت عددی از پیش تعیین شده است:
true -> 1
false -> 0
null -> 0
undefined -> NaN

❗️اگر مقدار داخل یک string غیر قابل تبدیل به عدد باشد، نتیجه NaN است:
"123" -> 123
"123AB" -> NaN

❗️برای تبدیل آبجکت‌ها (و subtypeهای آن مثل آرایه‌ها) ابتدا آبجکت به primitive تبدیل می‌شود.
سپس مقدار primitive با توجه به نکاتی که در بالا بررسی کردیم به عدد تبدیل می‌شود (کد داخل تصویر)

حالا در هر شرایط، و به هر روشی که یک مقدار را به عدد تبدیل کنیم، از این قوانین تبعیت می‌شود:
Number(false) -> 0
+false -> 0
false * 1 -> 0

#quicktip #js #coercion

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

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

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

#quicktip #js #coercion

@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
This media is not supported in your browser
VIEW IN TELEGRAM
با استفاده از قابلیت workspaces در گوگل کروم می‌توانیم کاری کنیم که تغییراتی که در devtools انجام می‌دهیم،‌ در فایل‌های پروژه اعمال شوند.

#quicktip #devtools

@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
This media is not supported in your browser
VIEW IN TELEGRAM
در گوگل کروم می‌توانیم داخل یک پنجره‌ی devtools، یک devtools دیگر باز کنیم (یعنی devtools برای devtools)!

در این ویدیو با استفاده از این قابلیت فریم‌های کند برنامه را پیدا می‌کنیم.

#quicktip #devtools #trick

@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
This media is not supported in your browser
VIEW IN TELEGRAM
در قسمت‌های مختلف chrome devtools می‌توانیم یک مقدار را در یک متغیر گلوبال ذخیره کنیم تا به راحتی در کنسول به آن دسترسی داشته باشیم.

در ویدیو، کاربرد این ویژگی برای دسترسی به اطلاعات یک انیمیشن، dom element و response object را می‌بینید.

#quicktip #devtools

@ProGraphs
احتمالا دقت کرده‌اید که در CSS با استفاده از پراپرتی display می‌توانیم هم نحوه‌ی قرار گرفتن خود عنصر و هم نحوه‌ی چیده شدن فرزندان عنصر در صفحه را تعیین کنیم.
به عنوان مثال:
- با استفاده از display: flex خود عنصر Block می‌شود و فرزندان آن از قوانین flex تبعیت می‌کنند.
- با استفاده از display: inline-flex خود عنصر به صورت inline نمایش داده می‌شود و فرزندان آن از قوانین flex تبعیت می‌کنند.
- با display: block خود عنصر به صورت Block در می‌آید و فرزندان آن از قوانین normal flow تبعیت می‌کنند و ...

همچنین می‌دانیم که display: none هم خود عنصر و هم فرزندان آن را از صفحه حذف می‌کند.
اما حالا با ویژگی جدید display: contents می‌توانیم کاری کنیم که خود عنصر از صفحه حذف شود،‌ ولی فرزندان آن در صفحه باقی بمانند!

در این مقاله می‌توانید کاربرد عملی این ویژگی را ببینید:
https://rachelandrew.co.uk/archives/2016/01/29/vanishing-boxes-with-display-contents/

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

#quicktip #js #trick

@ProGraphs
This media is not supported in your browser
VIEW IN TELEGRAM
با استفاده از media query inspector در گوگل کروم، می‌توانیم تمام media queryهای تعریف شده داخل یک صفحه را ببینیم و اعمال کنیم!

#quicktip #devtools

@ProGraphs
This media is not supported in your browser
VIEW IN TELEGRAM
فرض کنید بر روی یک عنصر هم translate، هم scale و هم rotate اعمال کرده‌ایم.

حالا می‌خواهیم در حالت hover، فقط مقدار rotate را تغییر دهیم.
متاسفانه برای این کار مجبوریم تمام مقادیر قبلی را هم تکرار کنیم!

با استفاده از متغیرهای CSS می‌توانیم این مشکل را حل کنیم (ویدیو را ببینید).

#quicktip #css #trick

@ProGraphs
احتمالا دقت کرده‌اید که وقتی مقادیر CSSی یک عنصر را در جاوااسکریپت می‌خوانیم، مقدار مورد نظر را به همراه واحد آن در یک string دریافت می‌کنیم:
100px

یعنی برای انجام محاسبات مجبوریم این string را parse کنیم و دوباره واحد مورد نظر را concat کنیم.

اما حالا با استفاده از api جدید CSS Typed OM می‌توانیم مقدار و واحد رو به صورت جداگانه در یک آبجکت دریافت کنیم و خیلی راحت‌تر استایل‌های عناصر را تغییر دهیم.

برای مقایسه‌ی بهتر، در این ویدیو هم با CSSOM و هم با CSS Typed OM عرض یک عنصر را دو برابر می‌کنیم.

#quicktip #css #houdini

@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
پراپرتی transform-style در CSS مشخص می‌کند که فرزندان یک عنصر در یک سطح صاف هستند، یا باید در یک فضای سه بعدی نمایش داده شوند.

به این ترتیب با استفاده از transform: rotate و transform-style می‌توانیم یک عنصر را دور یک عنصر دیگر قرار دهیم!

codepen.io/prographs/pen/Rwwgwmo

#quicktip #css #trick

@ProGraphs
احتمالا دقت کرده‌اید که وقتی می‌خوایم یه پراپرتی CSS رو تو حالت hover یا ... تغییر بدیم، مجبوریم اون پراپرتی رو دوباره با مقادیر جدید تکرار کنیم.

اما حالا با متغیرهای CSS و تابع calc میتونیم بدون تکرار کردن دوباره‌ی پراپرتی‌ها، بین دو مقدار switch کنیم. به عنوان مثال:
transform: rotate(calc(var(--i) * 45deg));
top: calc(var(--i) * 10px);

توی این کد اگر متغیر i = 0 باشه، عنصرمون rotate و top نداره.
حالا برای اینکه عنصر رو 45deg بچرخونیم و top 10px بهش بدیم، فقط کافیه مقدار متغیر i رو 1 کنیم!

دقت کنید که تو این ترفند داریم از ویژگی live بودن متغیرهای CSS استفاده می‌کنیم. پس با متغیرهای SASS نمیتونیم این کار رو انجام بدیم.

برای مقایسه‌ی بهتر، توی ویدیو پراپرتی‌های transform و background رو با استفاده از این ترفند (بدون تکرار کردن کردن پراپرتی‌ها) تغییر میدیم.

#quicktip #css #trick #dry

@ProGraphs
میدونیم که تغییر پراپرتی box-shadow با CSS جزو انیمیشن‌های نسبتا سنگین محسوب میشه و میتونه باعث کند شدن انیمیشن بشه.

اما با یه ترفند جالب میتونیم box-shadow یه عنصر رو خیلی روان‌تر animate کنیم.
به این صورت که یه pseudo element به اندازه‌ی خود عنصر تعریف میکنیم و box-shadow رو به این pseudo element میدیم. حالا کافیه opacity این pseudo element رو تغییر بدیم (به کد داخل عکس دقت کنید).

در واقع با این ترفند به جای پراپرتی box-shadow، پراپرتی opacity رو تغییر دادیم (animate کردن پراپرتی opacity برای مرورگر ساده‌تره)

کد کامل این ترفند رو میتونید اینجا ببینید.

ترفندهای مشابه برای تغییر بهینه‌تر طول و عرض عنصر هم وجود داره که در مطالب بعدی بررسی میکنیم :)

#quicktip #css #performance #trick

@ProGraphs