<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Bamdad</title>
        <link>https://virgool.io/feed/@bamdad</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-16 16:24:58</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/29148/avatar/6yyq3o.png?height=120&amp;width=120</url>
            <title>Bamdad</title>
            <link>https://virgool.io/@bamdad</link>
        </image>

                    <item>
                <title>پروتوتایپ‌های جاوااسکریپت</title>
                <link>https://virgool.io/@bamdad/%D9%BE%D8%B1%D9%88%D8%AA%D9%88%D8%AA%D8%A7%DB%8C%D9%BE%D9%87%D8%A7%DB%8C-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-hp3l33evkwtt</link>
                <description>وقتی به طور کلی از مفهوم کلاس‌ها تو برنامه‌نویسی صحبت میکنیم، معمولا این مثال میاد وسط که خود کلاس مثل یه نقشه‌س و اون نمونه یا  instance ای که ازش میسازیم، یه نمونه پیاده سازی شده از اون نقشه‌س. یعنی برای مثال اگه کلاس صندلی داریم، مثل نقشه ساخت صندلیه. وقتی از روی اون نقشه یکی بسازیم خود صندلیه. حالا وقتی یه صندلی ساختیم، اگه از نقشه پشتیشو حذف کنیم، پشتی صندلیمون از بین میره؟ یا اگه به صندلی‌مون یه کفی نرم اضافه کنیم به نقشه‌مون اضافه میشه؟ نه طبیعتا. پس انگار از روی نقشه یه کپی گرفتیم، یعنی همون اول یه رابطه اولیه دارن ولی بعدش کاملا جدا هستن. این رابطه اولیه میتونه با به ارث بردن بیشتری همراه باشه. همون طور که میدونیم مفهوم وراثت تو برنامه‌نویسی شی‌گرا (یا حالا خیلیا بهش میگن کلاس گرا یا class oriented) محبوبه. اونم مثل اینه که من که فرزند پدرمم ازش خیلی چیز ها به ارث بردم و اون ارتباط اولیه بوده، ولی اگه من الان پام بشکنه پای پدرم نمیشکنه! حالا این که بگیم از کلاس به instance ها کپی میشن یه مشکل رو بهمون نشون میده، توی جاوااسکریپت چیزی کپی نمیشه! برای همینه که بخش کلاس‌های جاوااسکریپت همیشه اون جوری که توقع داریم عمل نمیکنن و مثل مفاهیم کلاس‌ها تو جاوا یا ++c نیستن. عملا تلاش شده تا جاوااسکریپت از کلاس‌ها ساپورت کنه با این وجود که از پایه یه جور دیگه عمل میکنه. ما تا ابزارمون رو به اندازه کافی نشناسیم باید توقع باگ رو داشته باشیم. پس بیاین ببینیم حالا که نمیتونه کپی کنه چطوری عمل میکنه. حقیقت اینه که وقتی تو جاوااسکریپت یه نمونه از روی کلاس میسازیم، میاد یه آبجکت خالی برامون میسازه و اون رو به نقشه اصلیش، پروتوتایپش، لینک میکنه. این لینک میکنه تمام قشنگی عملکردشه. خود کلاس یه آبجکته. آبجکت‌ها یه عضو یا property دارن به نام prototype. توی پروتوتایپ به صورت پیش فرض کلی متد و متغیر هست. برای مثال toString توی پروتوتایپ آبجکته. گفتم وقتی از روی کلاس یه نمونه میسازیم میاد یه آبجکت خالی میسازه. این آبجکت هم خودش پروتوتایپ داره. حالا جایگزین اون عمل کپی کردن تو جاوااسکریپت اینه که میاد پروتوتایپ آبجکت رو به پروتوتایپ نقشه‌ش، کلاسش وصل میکنه! برای همین اگه ده ها نمونه از روی کلاسمون بسازیم، عملا پروتوتایپ تک تک این ابجکت‌ها به پروتوتایپ کلاسشون وصلن. با همین نگاه میشه وراثت تو خود کلاس‌ها رو هم دید. وقتی یه کلاس مادر داریم و یه کلاس فرزند میسازیم که از کلاس مادر به ارث میبره، عملا داریم یه ارتباطی بین پروتوتایپ فرزند با پروتوتایپ مادر میسازیم; برای همین property ها بینشون مشترک میشه و از فرزند بهشون دسترسی داریم. حالا ما در عین حال میتونیم این property ها رو بازنویسی هم بکنیم. یعنی اگه دوباره بهش مقدار بدیم، مقدار قبلیشو از دست میده و مقدار جدید میگیره. </description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Mon, 06 Apr 2020 02:56:40 +0430</pubDate>
            </item>
                    <item>
                <title>شیرجه تو مساوی های جاوااسکریپت</title>
                <link>https://virgool.io/@bamdad/%D8%B4%DB%8C%D8%B1%D8%AC%D9%87-%D8%AA%D9%88-%D9%85%D8%B3%D8%A7%D9%88%DB%8C-%D9%87%D8%A7%DB%8C-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-qbx7bvbhlxbt</link>
                <description>هممون میدونیم توی جاوااسکریپت برای بررسی مساوی بودن دو مقدار باید از === یا == استفاده کنیم. از هر جی‌اس دولوپری هم بپرسی تفاوت اینا چیه میگن === تایپ طرفین رو هم بررسی میکنه ولی == فقط مقدار طرفین رو بررسی میکنه. بیاین یه کار جالب بکنیم. بیاین از توی spec پیاده سازی عملوند های === و == رو ببینیم و بعدش به قسمتای عجیبش نگاه بندازیم. برای == داریم:پیاده سازی == در جاوااسکریپتو برای === داریم: پیاده سازی == در جاوااسکریپتخب، اولین نکته جالب اینه که وقتی از == استفاده میکنیم تایپ متغیر ها چک میشه، بر خلاف نظر عمومی که تایپ‌ها بررسی نمیشن. اگه یکسان باشت === براشون صدا زده میشه. توی === باید بدونیم که دوتا دروغی که مساوی‌ها بهمون میگن تو جاوااسکریپت همینجان. NaN و -0. بعدا مفصل بهشون میپردازیم و میگیم چه مواقعی حواسمون باشه گیرش نیفتیم. به == که دقت کنیم میبینیم هر کدوم از متغیرهامون null یه undefined باشن false میشه. پس میتونیم بجای بررسی جفتش با === اونارو با یکیش و با == بررسی کنیم. یعنی وقتی همزمان میخوایم چک کنیم variable === undefined || variable === null میتونیم فقط چک کنیم variable == null. طبق پیاده سازی == میبینیم که برای مقایسه مقدار، تایپ‌های دیگه رو تبدیل به عدد میکنه. برای آبجگت‌ها میبینیم که toPrimitive صدا زده میشه، و بعد از اینکه به تایپ پایه‌شون رسیدن مقایسه میشن. toPrimitive رو مفصل توی این پست گفتم. خب، بیاین چند نمونه از کارای عجیب جاوااسکریپت ببینیم.با 42 == [42] شروع کنیم که true برمیگرده. برای چراییش به یه بخشی از پست قبلی اشاره میکنم، سریالایز شدن آرایه. یعنی [42] میشه &quot;42&quot; که 42 == &quot;42&quot; قطعا true میشه.یه نمونه دیگه میشه به [] =! [] اشاره کرد که true میشه. چون همینو میشه به صورت ([] == [])! که میشه (false)! پس true میشه. اینجا باید به این دقت کنیم که تو آبجکت‌ها وقتو دو آبجکت شبیه هم داریم ولی از یک منبع کپی نشدن، == بینشون false برمیگرده. یعنی اگه عینا به یه ادرس مموری اشاره نکنن == بینشون false میشه. اینو میشه تو مثال بالا هم دید که دو آرایه خالی، که عین همن، ولی چون از یک منبع کپی نشدن و به دو آدرس مختلف از مموری اشاره میکنن ‌[] == [] میشه false.در آخر باید بگم که کلا این که === رو اولویت میدیم بهش یا == خیلی سلیقه‌ایه، ولی مهم اینه که به کدمون و به تایپ‌هاش اشراف داشته باشیم. تمام حالاتی که &quot;مجبور&quot; میشیم از === استفاده کنیم میتونیم به سادگی با انجام تبدیل تایپ‌ها قبلش یا بررسی و چک کردن تایپ‌ها قبلش از == استفاده کنیم. این که با کدوم استایل کد زدن رو ترجیح میدیم به سلیقمون/سلیقه تیممون برمیگرده. فقط لازمه کدو بشناسیم و عملکرد دقیق == و === رو بدونیم. </description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Fri, 03 Apr 2020 02:54:09 +0430</pubDate>
            </item>
                    <item>
                <title>جاوااسکریپت و کارای عجیبش [قسمت اول]</title>
                <link>https://virgool.io/@bamdad/%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D9%88-%DA%A9%D8%A7%D8%B1%D8%A7%DB%8C-%D8%B9%D8%AC%DB%8C%D8%A8%D8%B4-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-lpz7eobokvuu</link>
                <description>خیلیا میگن جاوااسکریپت خنگه چون مثالا &quot;41&quot; = &quot;1&quot; + 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  &amp;quotnull&amp;quot
undefined  &amp;quotundefined&amp;quot
true  &amp;quottrue&amp;quot
false  &amp;quotfalse&amp;quot
3.14159  &amp;quot3.14159&amp;quotحالا toString ای که برای array داریم برخورد جالبی داره، میاد ارایه رو serialize میکنه، یعنی &quot;1,2,3&quot; = [3, 2, 1]. قسمت عجیبش تو برخورد با null و undefinedـه، یعنی &quot;,&quot; = [null, undefined]!!! انگار تو سریالایز کردنش حذفشون میکنه!توی toNumber قسمت جالب اینه که اکثر مشکلا از یه جا شروع میشه. از اون جایی که ‌&quot;&quot; رو تبدیل میکنه به 0. خیلی عجیبه چون یه استرینگ خالی به معنی اینه که هیچ مقداری استرینگمون نداره، ولی 0 اصلا به این معنی نیست تو اعداد!! در نتیجه [&quot;&quot;] تبدیل میکنه به 0. چرا؟ چون برای تبدیلش به عدد اون toPrimitive رو صدا میزنه، toPrimitive اول valueOf و بعدش toString میکنه. با توجه به اینکه valueOf برای نتیجه‌ای نداره میره toString، قسمت قبل دیدیم برای تبدیل ارایه به استرینگ سریالایز میشه و دیدیم &quot;&quot; تبدیل میشه به &quot;0&quot;. نکته جالب toPrimitive اینه که به صورت بازگشتی ادامه میده تا به نیجه برسه. پس الان که toString براش &quot;0&quot; رو برگردوند دوباره toPrimitive اجرا میشه، toValue براش 0 رو برمیگردونه. حالا [null] و [undefined] چرا میشن 0؟ اینم باز به قسمت قبل برمیگرده، toValue نتیجه نمیده میره توی toString، دیدیم برای تبدیل ارایه به استرینگ null و undefined عملا حذف میشدن، پس [null] و [undefined] نتیجشون &quot;&quot; برمیگرده و همونطور که دیدیم تبدیل &quot;&quot; رو جاوااسکریپت تبدیل به 0 میکنه.ولی toBoolean راحت‌تر از بقیه عمل میکنه. toBoolean یه لیست داره از تمام مواردی که false محسوب میشن، هر چیزی خارج از این لیستو به true تبدیل میکنه. این لیستو ببینیم:false
&amp;quot&amp;quot
0, -0
null
undefined
NaNپس عملا هر مقداری که بخواد به بولین تبدیل بشه فقط چک میشه که تو این لیست هست یا نه، اگه بود false و اگه نبود true میشه.</description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Thu, 02 Apr 2020 02:38:32 +0430</pubDate>
            </item>
                    <item>
                <title>ری‌اکت چطوری re-render میکنه؟</title>
                <link>https://virgool.io/@bamdad/react-rerender-ls4fwh1oe5ws</link>
                <description>وقتی از ری‌اکت استفاده میکنیم، به جایی میرسیم که متد render رو یه تابع میبینیم که درخت المنت های ری‌اکت رو میسازه. با آپدیت state یا prop تابع render یه درخت متفاوت از المنت ها بر میگردونه. ری‌اکت باید بفهمه بهینه ترین راه برای آپدیت رابط کاربری چیه تا با درخت جدید همخوانی داشته باشه.الگوریتم های عمومی برای حل مشکل تبدیل یک درخت، به درخت دیگه وجود دارن، اما اردرشون  (O(n3، که n تعداد المنت های درخته.اگه ری‌اکت از این الگوریتم ها استفاده میکرد، نشان دادن ۱۰۰۰ المنت، یک میلیارد مقایسه لازم بود، که خیلی هزینه زیادی میشد. بجاش ری‌اکت از الکوریتمی با اردر (O(n استفاده میکنه که بر پایه دو فرضه: اول اینکه دو المنت از دو نوع متفاوت، درخت متفاوتی تولید میکنن. دوم دولوپر میتونه با key بگه کدوم المنت فرزند ممکنه ثابت بمونه.الگوریتم Diffingاول از همه ری‌اکت المنت روت دو درخت رو باهم مقایسه میکنه. اگه متفاوت بودن کل درخت رو از اول میسازه. زمانی که درخت قدیمی رو نابود میکنه، نود های DOM قدیمی رو حذف میکنه. یعنی عملا کامپوننت ها componentWillUnmount میشن. برای تشکیل درخت جدید کامپوننت ها componentWillMount میشن و بعدش componentDidMount (متد های لایف سایکل رو اینجا ببینید).زمانی که ری‌اکت دو المنت DOM رو مقایسه میکنه، اگه نوع یکسانی داشته باشن، ری‌اکت صفات هر دو رو بررسی میکنه، نود های زیری رو ثابت نگه میداره و تغییرات رو آپدیت میکنه.وقتی style رو مقایسه میکنه، میدونه کدوم ویژگی رو آپدیت کنه. برای مثال:&lt;div style={{color: &#039;red&#039;, fontWeight: &#039;bold&#039;}} /&gt;
&lt;div style={{color: &#039;green&#039;, fontWeight: &#039;bold&#039;}} /&gt;زمان تبدیل المنت اول به دوم ری‌اکت فقط color رو تغییر میده و میدونه fontWeight رو کاری نداشته باشه.حالا که آپدیت انجام شد، ری‌اکت componentWillReceiveProps و componentWillUpdate رو از متد های لایف سایکل صدا میزنه. بعد هم render رو صدا میزنه.برای مقایسه فرزند های یه نود، ری‌اکت روی لیست هر دو همزمان حرکت میکنه و هرجا تفاوتی باشه یه جهش ایجاد میکنه. اینکه از بالا به پایین لیستو طی میکنه وقتی خوبه که مثلا به ته لیست چیزی اضافه شده باشه، اما فرض کنیم اولین آیتم لیست متفاوت و بقیش یکسان باشه، این مشکل اصلیشه.برای حل این مشکل ری‌اکت از key پشتیبانی میکنه. وقتی فرزند ها key دارن، ری‌اکت دو کلید یکسانو باهم مقایسه میکنه و این بهینه تره. پیدا کردن یه کلید برای هر آیتم سخت نیست. ممکنه هر آیتم id خودشو داشته باشه، میتونیم از id استفاده کنیم. یا برای مثال، اگه لیست ترتیب ثابتی داره، میشه از index هر آیتم استفاده کرد.</description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Mon, 06 May 2019 21:46:03 +0430</pubDate>
            </item>
                    <item>
                <title>یکم هوک ری‌اکت، useCallback و useMemo</title>
                <link>https://virgool.io/@bamdad/react-hooks-hjgau4kndqvy</link>
                <description>به کمک هوک های useCallback و useMemo میتونیم از re-render های غیر ضروری جلوگیری، و کد بهینه تری داشته باشیم.اول یکم هوک. هوک ها ویژگی جدید ری‌اکت هستن که اجازه میدن از ویژگی های کلاس ها توی کامپوننت های فانکشنال استفاده بشه. با هوک ها میتونیم استیت بسازیم و از متد های لایف سایکل استفاده کنیم.با  useState میتونیم برای متغیرمون استیت بسازیم:const [value, setValue] = useState(defaultValue)با useEffect میتونیم ساید افکت بسازیم:useEffect(() =&gt; {
//code goes here...
, [dependency]
});آرایه داده شده توی پارامتر ها این اجازه رو میده که وقتی مقداری از آرایه تغییر کرد ساید افکت رو انجام بده. این طوری میتونیم متد لایف سایکل بسازیم.مثلا با هوک میتونیم به اپ حالت شب اضافه کنیم، یا مثلا با استیت ها فرم بسازیم.و اما useCallback و useMemo. هر دو یه تابع و یه آرایه‌ از dependency ها رو ورودی میگیرن. اگه یکی از مقادیر آرایه تغییر کنه خروجی عوض میشه و اگه تغییر نکنه، مقدار کش شده برگردونده میشه.useCallback(
    someFunction()
}, [dependencies])

useMemo(() =&gt; {
    someFunction()
}, [dependencies])باید بدونیم که اگه آرایه خالی بجای dependency ها بدیم بهش، یا اصلا آرایه ندیم، useCallback یک کال‌بک ذخیره شده، و useMemo یک مقدار ذخیره شده که نتیجه‌ی پارامتر های تابع هست رو بر میگردونه.اگه با حجم زیادی از دیتا سروکار داریم، useMemo انتخاب خوبیه چون کار رو یکبار با اولین رندر انجام میده و بعد از اون ورژن کش شده رو با هر رندر بر میگردونه.اما useCallback یکم متفاوته. برای مثال، یه کامپوننت مادر که زیاد re-render میشه، توی کامپوننت مادر یه کامپوننت فرزند داریم که یه تابع میگیره. با هر بار re-render شدن کامپوننت مادر، تابع فرزند اجرا میشه، بدون اینکه لزومی داشته باشه. حالا اگه useCallback رو بجای یک prop بدیم، مشکل حل میشه. چون تابع وقتی اجرا میشه که آرایه dependency تغییر کنه. پس هر re-render یک تابع کش شده میگیره و باز اجرا نمیشه، مگر وقتی که لازم باشه. </description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Mon, 06 May 2019 20:25:23 +0430</pubDate>
            </item>
                    <item>
                <title>لایف سایکل ها در ری‌اکت</title>
                <link>https://virgool.io/@bamdad/react-lifecycle-uqb5zdoouvlw</link>
                <description>کامپوننت های ری‌اکت چند متد لایف سایکل بیشتر ندارن، ولی خیلی مهمه که درست و بجا ازشون استفاده بشه. خیلی کوتاه بخونیم این متد ها کدوما هستن و هر کدوم چه کاری رو انجام میدن.به طور کلی متد های لایف سایکل به سه دسته اصلی تقسیم میشن، Mount ،Update ،Unmount.Mountکلا وقتی ری‌اکت یه نسخه از کامپوننت رو میسازه و توی DOM قرار میده عملا mount انجام داده . Mount چهار متد داره.constructor()componentWillMount()render()componentDidMount()Updateزمانی که state یا props کامپوننت تغییری میکنن، آپدیت کامپوننت انجام میشه. آپدیت کامپوننت به این معناست که کامپوننت باید دوباره رندر بشه. به همین دلیل متد های زیر استفاده میشن:componentWillReceiveProps()shouldComponentUpdate()componentWillUpdate()render()componentDidUpdate()Unmountزمانی که عمر کامپوننت تموم میشه و باید از DOM حذف بشه متد زیر استفاده میشه:componentWillUnmount()اگه به ترتیب به متد ها نگاه کنیم میبینیم کاملا منطقیه. یکبار دیگه به اسم متد ها پشت هم دقت میکنیم.componentWillMountcomponentDidMountcomponentWillReceivePropsshouldComponentUpdatecomponentWillUpdatecomponentDidUpdatecomponentWillUnmountاگرچه تعداد متد ها زیاد نیست، اما مهمه بجا استفاده بشن. برای همین به طور دقیق به تک تک متد ها میپردازیم.componentWillMount()وقتی ری‌اکت میخواد یه کامپوننت رو رندر کنه این متد رو صدا میزنه. این متد فقط یک بار صدا زده میشه. با توجه به اینکه این متد قبل از متد render صدا زده میشه، componentWillMount تنها متد لایف سایکله که برای سرور ساید رندرینگ سمت سرور صدا زده میشه.توی این متد میتونیم از this.setState استفاده کنیم. البته مهمه بدونیم که ممکنه re-rendering انجام نشه وقتی syncronous استیت رو ست میکنیم. بهتره مقدار پیش فرض استیت رو توی constructor ست کنیم بجای componentWillMount.componentDidMount()وقتی این صدا زده میشه ری‌اکت کامپوننت ها رو رنده کرده و توی DOM قرار داده. البته اگه مقدار دهی هست که به DOM نیاز داره باید همینجا انجام بدیم.توی این متد هم میتونیم از this.setState استفاده کنیم، و بعدش کامپوننت re-render میشه.از componentDidMount میتونیم برای گرفتن دیتا از سرور با AJAX استفاده کنیم، یا مثلا برای اضافه کردن event listener ها.componentWillReceiveProps()وقتی کامپوننت مجموعه جدیدی از prop ها میگیره این متد صدا زده میشه. البته باید بدونیم که ری‌اکت خودش اینو صدا میزنه، حتی اگه prop ها تغییری نکرده باشن، پس حتما باید this.props رو با nextProps مقایسه کنیم که بیخودی استیت رو باز ست نکنیم.توی این متد هم میتونیم از this.setState برای ست کردن استیت استفاده کنیم.اگه استیتی داریم که نتیجه محاسبه روی چند prop میتونیم محاسبه رو اینجا انجام بدیم.shouldComponentUpdate()به طور پیش فرض این متد پیاده سازی شده نیست، پس هر تغییر توی props یا states باعث میشه کامپوننت re-render بشه، برای همین اگه بخوایم از رندر های غیر ضروری جلوگیری کنیم میتونیم اینجا انجامش بدیم. قابل توجه که این متد برای رندر اولیه صدا زده نمیشه.توی shouldComponentUpdate نمیتونیم از setState استفاده کنیم.componentWillUpdate()این متد دقیقا قبل از هر re-render فراخوانی میشه و برای رندر اولیه صدا زده نمیشه.توی componentWillUpdate نمیتونیم از setState استفاده کنیم. اگه برای تغییرات  props مجبور بودیم، میتونیم از componentWillReceiveProps استفاده کنیم.اینجا میتونیم آماده سازی قبل از رندر رو انجام بدیم. و البته، از اونجایی که قبل از متد render صدا زده میشه نمیتونیم کاری رو که نیاز به DOM داره انجام بدیم.componentDidUpdate()دقیقا بعد از آپدیت شدن کامپوننت، ری‌اکت componentDidUpdate رو صدا میزنه. این متد برای رندر اولیه صدا زده نمیشه.توی این متد میتونیم از setState استفاده کنیم.اگه باید روی DOM بعد از آپدیت کاری بکنیم، از این متد استفاده میکنیم. برای مثال آپدیت رابط کاربری با لایبرری های 3rd party.componentWillUnmount()دقیقا بعد از اینکه ری‌اکت کامپوننت رو از بین برد این متد فراخوانی میشه.این متد جای مناسبیه برای اینکه تمیزکاری نهایی کامپوننتو انجام بدیم، مثلا event listeners ها رو حذف کنیم یا تایمر رو قطع کنیم یا المنت های DOM رو که با componentDidMount ساختیم رو از بین ببریم و...</description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Mon, 06 May 2019 19:33:51 +0430</pubDate>
            </item>
                    <item>
                <title>از g تا گوگل</title>
                <link>https://virgool.io/@bamdad/google-jpgtwzhjduf3</link>
                <description>یه روز عادی، مرورگر رو باز میکنیم تا چیزی رو سرچ کنیم. از اولین کلیدی که توی url باکس مرورگر میزنیم، تا دیدن صفحه گوگل روی مانیتورمون کلی اتفاق میوفته. آماده‌ای دقیق ببینیم چه اتفاقاتی؟؟کلید g روی کیبورد زده میشه، مرورگر یه event دریافت میکنه. اینکه چطور از فشار دادن فیزیکی یه دکمه، یا تپ کردن روی صفحه نمایش به ایونت توی مرورگر میرسیم رو جلوتر میگم. مرورگر با دریافت این ایونت تابع auto-complete رو صدا میزنه. بسته به الگوریتم مرورگرمون یا اینکه صفحه private/incognito  هست یا نه، زیر باکس url تعدادی لینک پیشنهاد شده میبینیم. بیشتر این الگوریتم ها بر مبنای تاریخچه مرورگرمون، بوکمارک ها، کوکی ها یا جملات زیاد سرچ شده این پیشنهاد ها رو ترتیب بندی میکنن. حالا توی باکس url داریم google.comدکمه enter زده میشه. مدار الکتریکی مخصوص این دکمه بسته میشه، این یعنی جریان خیلی کوچکی برقرار میشه و به مدار منطقی کیبورد وضعیت دکمه‌ها رو میگه. حالا این پالس آماده‌ی ارسال به کامپیوتر از یکی از راه های کابل یا بلوتوث به پورت usb، یا کیبورد مجازی مثل کیبورد صفحه‌های لمسی.دریافت و تحلیل این ورودی روی سیستم عامل ها با هم تفاوت داره.برای مثال روی مک OS X ایونت KeyDown از جنس NSEvent ارسال میشه. سیگنال ورودی I/O kit رو صدا میزنه و سیگنال رو به درایور کیبورد میفرسته. درایور این سیگنال رو به یه key code ترجمه میکنه و به صف ایونت های اپلیکیشنی که فعاله میفرسته، و اپلیکیشن از صف ایونت ها رو به ترتیب اجرا میکنه.چیزی که توی باکس url نوشتیم، سرچ باید بشه یا یه url کامله؟ یه url شامل پروتوکل (مثل http) یا دامنه معتبره. مرورگر بررسی میکنه که هاست نیم ورودی شامل غیر از a-z, A-Z, 0-9, - یا . میشه یا نه، تو مثال ما که google.com این مشکل پیش نمیاد، اما اگه شامل بود punucode encoding انجام میده.مرورگر اول لیست HSTS رو چک میکنه، اگه دامنه ورودی توی لیست بود با پروتوکل https بهش درخواست میزنه. این لیست روی خود مرورگر هست و لیست سایت هایی که فقط با https میشه بهشون درخواست زد. البته اگه اولین درخواست با http زده بشه، پاسخ سرور حاوی درخواستی از مرورگر خواهد بود که درخواست ها رو روی https بزنه. البته همین یک درخواست روی http میتونه کاربر رو در برابر downgrade attack آسیب پذیر کنه، به همین دلیل مرورگر های مدرن لیست HSTS دارن.چک کردن DNS. مرورگر اول کش مرورگر رو برای دامنه جست و جو میکنه. اگه پیدا نکرد، تابع getHostByName رو برای جست و جو صدا میکنه. این تابع اول بررسی میکنه که این url مرجع local روی کامپیوتر داره یا نه. اگه url مرجع local نداشت، توی کش هم پیدا نشد، مرورگر  سرور DNS درخواست میزنه، که معمولاً روتر local یا سرور کش IPS هست. اگه DNS server روی همون زیر شبکه ای (subnet) بود که شبکه ما دنبال میکنه، فرایند ARP برای اون DNS اجرا میشه. اگه روی اون subnet نبود، ARP برای geteway ip پیش فرض اجرا میشه.برای ارسال ARP شبکه ما برای جست و جو به ip مقصد و MAC address اینترفیسی که قراره ازش APR ارسال بشه نیاز داره. اول بررسی میشه که ip مقصد توی کش هست یا نه، اگه بود ip همون MAC.اگه ip ورودی توی کش ARP نبود، روتر چک میشه که ببینیم ip توی شبکه داخلی هست یا نه. اگه بود از اینترفیسی که با اون subnet در ارتباطه استفاده میکنه. اگه نبود از اینترفیسی استفاده میکنه که subnet  پیش فرض geteway رو استفاده میکنه. بعد MAC address شبکه بررسی میشه و در نهایت یه درخواست ARP ارسال میشه.یه ARP request به این شکله:Sender MAC: interface:mac:address:here
Sender IP: interface.ip.goes.here
Target MAC: FF:FF:FF:FF:FF:FF (Broadcast)
Target IP: target.ip.goes.hereحالا اگه کامپیوتر مستقیم به روتر وصل باشه، روتر یک ARP reply میفرسته.اگه کامپیوتر به هاب وصل باشه، هاب ARP request رو میده. اگه روتر به همون کابل وصل باشه، یه ARP reply میفرسته.اگه کامپیوتر به سویچ وصل باشه، سویچ جدول CAM/MAC داخلیشو چک میکنه که کدوم پورت اون MAC address ای که میخوایمو داره. اگه سویچ MAC address رو پیدا نکنه به تمام پورت ها ARP request رو میزنه. اگه پیدا بکنه به همون پورت که MAC address رو داره ARP request میزنه. اگه روتر روی همون کابل باشه ARP reply میده.یه ARP reply به این شکله:Sender MAC: target:mac:address:here
Sender IP: target.ip.goes.here
Target MAC: interface:mac:address:here
Target IP: interface.ip.goes.hereحالا که شبکه ما ip ی DNS server یا geteway پیش فرض رو داره میتونه به فرایند DNS ادامه بده.پورت ۵۳ باز میشه تا یک درخواست UDP به DNS server ارسال بشه (اگه اندازه پاسخ خیلی بزرگ باشه TCP استفاده میشه). اگه DNS سرور های local و ISP نداشتنش ، یه جست و جوی بازگشتی درخواست میشه و لیست DNS سرور ها بررسی میشه تا به SOA برسیم.باز کردن یک سوکت. زمانی که مرورگر ip سرور مقصد رو پیدا کرد، با ip و پورت url (برای http پورت پیش فرض ۸۰ و برای https ۴۴۳) تابع socket رو صدا میزنه و یک TCP socket stream درخواست میکنه (AF_INET/AF_INET6 و SOCK_STREAM).این درخواست اول به لایه‌ی transport که TCP ساخته شده فرستاده میشه. پورت مقصد به هدر اصافه شده، و پورت منبع از بین بازه‌ی داینامیک کرنل انتخاب میشه. این فرستاده میشه به لایه‌ی شبکه که یک ip header اضافه میکنه، و ip سرور مقصد اضافه میشه. این مجموعه به لایه‌ی لینک فرستاده میشه. یک هدر بهش اضافه میشه که شامل MAC address ماشین و geteway (روتر لوکال). اگه کرنل MAC address رو نمیشناخت، . ARP درخواست میده تا پیداش کنه.حالا این مجموعه آمادست تا از یکی از راه های اترنت، وای‌فای یا شبکه cellular منتقل بشه.TLS handshakeکامپیوتر کلاینت یک ClientHello میفرسته به سرور با TLS، که لیست الگوریتم های رمزنگاری و متد های فشرده‌ سازی داره. سرور با ServerHello جواب میده، با ‌TLS و الگوریتم رمزنگاری و متد فشرده سازی مورد نظر و سرتیفیکیت عمومی تایید شده توسط CA. این سرتیفیکیت شامل یک کلید عمومیه که توسط کلاینت برای رمزگذاری بقیه‌ی handshake استفاده میشه تا زمانی که هردو طرف کلید یکسان داشته باشن.کلاینت با بررسی سرتیفیکیت از لیست سرتیفیکیت های مورد اعتماد CA، اعتبار سرتیفیکیت رو میسنجه. اگه اعتماد برقرار بود، کلاینت یک رشته psedu-random bytes تولید میکنه و با اون کلید رمزگذاریش میکنه. این رشته برای تعیین کردن یکسان بودن کلید به کار میره. سرور این رشته رو با کلید خصوصیش رمزگشایی میکنه و از اون برای تولید کلید اصلیش استفاده میکنه. کلاینت یک پیام finished به سرور میفرسته، hash رمزگذاری شده از انتقال تا این نقطه توسط کلید متقارن. سرور hash خودشو تولید میکنه و hash های فرستاده شده از کلاینت رو رمزگشایی میکنه تا نشون بده یکسانند. اگه بودن، سرور هم پیام finished خودشو میفرسته و کلید متقارن رو رمزگذاری میکنه. حالا دیگه اپلیکیشن دیتا رو رمزگذاری شده با کلید متقارن انتقال میده.پروتوکل HTTPاگه مرورگر توسط گوگل نوشته شده باشه، بجای http از پروتوکل SPDY استفاده میکنه تا اطلاعات رو بگیره.اگه کلاینت از http استفاده بکنه و SPDY رو ساپورت نکنه، درخواستشو به شکل زیر میفرسته:GET / HTTP/1.1
Host: google.com
Connection: close
[other headers]که [other headers] به key-value pair هایی اشاره میکنه که سرتیفیکیت http دارن. HTTP/1.1 نشون میده که بعد از پایان پاسخ سرور کانکشن بسته بشه. بعد از فرستادن درخواست و هدر به سرور یک خط خالی ارسال میشه به معنی اینکه درخواست تمومه. سرور هم با دادن کد ریسپانس جواب میده:200 OK
[response headers]بعدش یک خط خالی و سپس محتوای html صفحه‌ی google.com. سرور ممکنه کانکشن رو ببنده یا ممکنه طبق درخواست کلاینت توی هدر کانکشن رو باز نگه داره برای درخواست های بعدی.بعد از پارس شدن html مرورگر همین فرایند رو برای فایل های دیگه (مثل عکس ها، CSS، آیکن و...) تکرار میکنه، فقط بجای GET /HTTP/1.1 از طریق GET /$(URL) HTTP/1.1 درخواست رو میفرسته.مسئولیت رسیدگی به درخواست‌ها و پاسخ‌ها رو HTTPD (یا همون http Deamon) بر عهده داره. معروف ترین اونها Apache و nginx برای لینوکس و IIS برای ویندوز هستند. سرور درخواست هارو به چند قسمت تقسیم میکنه، متد درخواست (که یکی از GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE)، دامنه (تو مثال ما google.com) و درخواست یک زیر صفحه. سرور تایید میکنه که یک میزبان مجازی برای پاسخگویی به google.com هست و سرور تایید میکنه که google.com یک GET request رو میپذیره.سرور تایید میکنه که کلاینت اجازه‌ی دسترسی به این صفحه رو داره (با ip یا انواع روش های احراز هویت)پشت مرورگر دو بخش هست، یکی پارسر، که کارش پارس کردن فایل های HTML, CSS, JS. یکی هم Rendering، که کارش تولید درخت DOM و رندر کردن اون و جا گذاریش تو صفحه و رنگ آمیزیشه.کار مرورگر اینه که منبعی رو که انتخاب کردیم رو با درخواست زدن به سرور روی صفحه نمایش بده. این منابع معمولا HTML هستن ولی گاهی عکس، pdf یا داده های دیگه‌ای هستن. این منابع با url نشون داده میشن. اکثر مرورگر ها، المان های یکسیانی دارن، مثلا همه باکس url برای ورودی گرفتن دارن یا دکمه‌ی صفحه‌ی قبل/بعد، بوکمارک، ریفرش و... دارن.بطور کلی مرورگر ها چند بخش دارن. رابط کاربری (تمام چیزی که میبینیم)، browser engine‌ (رابط کاربری رو به موتور رندرینگ وصل میکنه)، موتور رندرینگ (ورودی فایل های htmlو css رو میگیره و روی صفحه نمایش میده)، نتورکینگ (که کارش درخواست های سرویس هاست مثل http request و...)، UI backend (که ویجت ها مثل باکس ها رو میکشه)، موتور جاوااسکریپت (که فایل های js رو اجرا میکنه) و ذخیره سازی اطلاعات.موتور رندرینگ از بخش نتورکینگ محتوای html رو در تکه های ۸ کیلو‌بایتی میگیره و اجرا میکنه. پارسر html المان های فایل رو به درخت المان ها ارسال میکنه. این درخت شامل المان های DOM و attribute nodes. DOM مختصر شده‌ی Document Object Model که شیوه‌ی ارایه المان های html به بقیه مثل js هست.الگوریتم پارس html به شیوه‌ی نرمال بالا به پایین یا پایین به بالا نیست. این الگوریتم شامل دو بخش tokenization و tree construction.وقتی پارس html تموم شد، مرورگر شروع میکنه به گرفتن منابع خارجی مثل عکس، css، فایل های جاوااسکریپت و...فایل های css با تگ های &lt;style&gt; پارس میشن. فایل ها به styleSheet object پارس میشن، که هر آبجکت شامل قوانین css. پارسر css میتونه از بالا به پایین یا پایین به بالا باشه.برای رندر صفحه درخت frame یا درخت رندر، از روی درخت DOM ساخته میشه و برای هر نود محاسبات css انجام میشه. توی درخت frame از پایین به بالا با جمع کردن طول المان ها، طول کامپوننت ها محاسبه میشه. همینطور برای محاسبه‌ی ارتفاع کامپوننت ها از پایین به بالا با جمع کردن ارتفاع نود ها، به ارتفاع کامپوننت میرسیم. با نتایج این محاسبات به مختصات هر نود میرسیم. حین فرایند رندر کردن صفحه لایه‌ی گرافیکی میتونه از GPU استفاده کنه. زمانی که از GPU برای رندر کردن صفحه استفاده میشه، graphical software layer کار رو به چندین قسمت تقسیم میکنن تا از توانایی پارالل GPU برای محاسبات float point ها استفاده بشه.بعد از اتمام رندرینگ مرورگر ممکنه اسکریپت های ظاهری یا تعاملی رو اجرا کنه. همچنین پلاگین های فلش یا جاوا ممکنه اجرا بشن. خود این اسکریپت ها ممکنه network request هایی بزنن که باز هم همین فرایند رندر شدن صفحه طی میشه.</description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Fri, 12 Apr 2019 22:22:41 +0430</pubDate>
            </item>
                    <item>
                <title>تایپ اسکریپت از صفر تا نیم</title>
                <link>https://virgool.io/JavaScript8/%D8%AA%D8%A7%DB%8C%D9%BE-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D8%A7%D8%B2-%D8%B5%D9%81%D8%B1-%D8%AA%D8%A7-%D9%86%DB%8C%D9%85-y2b5w5hwougd</link>
                <description>مقدمه و اشنایی کوتاهی با تایپ اسکریپت تایپ اسکریپت یه زبان اُپن‌سورس که مایکروسافت سال ۲۰۱۲ معرفیش کرد. تایپ اسکریپت موفقیت اولیشو بخاطر زبان انگولار۲ بودن به‌ دست آورد؛ اما بین دولوپر های Vue و ری‌اکت هم محبوبیت پیدا کرد. هدف اصلی تایپ اسکریپت این بود که با اضافه کردن حساسیت نوع و تایپ داده جاوااسکریپت رو مقیاس پذیرتر و قابل اعتماد تر بکنه. این یعنی میتونیم هنگام تعریف کردن متغیر، نوع متغیر رو هم مشخص کنیم. این کار باعث میشه به باگ کمتری بر بخوریم، راحت تر از درست کار کردن کدمون مطمئن بشیم و راحت تر کدمونو مستند سازی کنیم.انواع داده‌ای که تو تایپ اسکریپت استفاده میکنیم، همونایین که تو جاوااسکریپت استفاده میکنیم. یعنی یا از انواع built-in استفاده میکنیم (مثل string، boolean، void، null، undefined) یا از انواعی که خودمون میسازیم یا همون user-defined ها (مثل enum، class، interface، tuple) یا از any. استفاده از any مثل اینه که حساسیت تایپ متغیر رو نادیده بگیریم.تایپ اسکریپت کد های جاوااسکریپت رو ساپورت میکنه و سینتکس مشابه‌ای هم دارن، پس کد زدن با تایپ اسکریپت برای دولوپر های جاوااسکریپت سخت نیست.حالا بیاین یکم امتحانش کنیم.برای شروع کد زدن با تایپ اسکریپت باید نصبش کنیم، که این کارو با npm میکنیم. یعنی توی ترمینال میزنیمnpm install -g typescript فایل های تایپ اسکریپت فرمت ts. دارن و مرورگر های ما نمیشناسنش. پس باید فایل های ts. رو کامپایل کنیم. با دستور tsc فایل تایپ اسکریپت رو به js. تبدیل میکنیم، فرمتی که برای مرورگر ها قابل اجراست.پس با اجرایtsc myCode.tsفایل myCode.js تحویل میگیریم که روی مرورگر ها قابل اجراست. تایپ اسکریپت تمام ویژگی های زبان شی‌گرا مثل کلاس ها و اینترفیس ها رو داره. کلاس نوعی قالب یا الگو برای ساخت شی محسوب میشه. برای مثال:class Food {
name: String;
calories : Number;
isVegan: Boolean;

constructor(name: String, calories: Number, isVegan: Boolean){
    this.name = name;
    this.calories = calories;
    this.isVegan = isVegan;
    }

displayFood(): void {
    console.log(`${this.name} contains ${this.calories} Calories.`)
    }
    }مثال ساده بالا کلاس Food رو نشون میده.اینترفیس ها از مفاهیم کارامد و مهم تایپ اسکریپت هستن که به ما اجازه میدن ساختار کلی متغیر ها رو مشخص کنیم. اینترفیس مثل قرارداد نوشته شده ای هستن که object باید مطابق اون عمل کنه. برای مثال:const Food = {
name: &#039;Burger &#039;,
calories: 450,
isVegan: false,
display() =&gt; { console.log(&#039;Burger&#039;s awesome!&#039;) }
}با توجه به Food میتونیم ساختارشو بصورت:{
name: String,
calories: Number,
isVegan: Boolean,
display(): void
}بنویسیم. حالا اکه بخوایم این ساختار قابلیت استفاده مجدد داشته باشه از interface استفاده میکنیم. یعنی:interface FoodInterface {
name: String,
calories: Number,
isVegan: Boolean,
display(): void
}

const Food: FoodInterface = {
name: &#039;Burger &#039;,
calories: 450, 
isVegan: false, 
display() =&gt; { console.log(&#039;Burger&#039;s awesome!&#039;) }
}امیدوارم این پست براتون جالب بوده باشه. ممنون که تا اخرش خوندین. </description>
                <category>Bamdad</category>
                <author>Bamdad</author>
                <pubDate>Mon, 08 Apr 2019 21:04:26 +0430</pubDate>
            </item>
            </channel>
</rss>