<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های سید آرین حسینی</title>
        <link>https://virgool.io/feed/@arianhosseini</link>
        <description>Solidity Developer | Blockchain DApp Developer</description>
        <language>fa</language>
        <pubDate>2026-06-07 03:31:02</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/59524/avatar/JdL9Hq.jpg?height=120&amp;width=120</url>
            <title>سید آرین حسینی</title>
            <link>https://virgool.io/@arianhosseini</link>
        </image>

                    <item>
                <title>Enums در Solidity سالیدتی</title>
                <link>https://virgool.io/Solidity/enums-in-solidity-tew4kagg10km</link>
                <description>سلام، ممکنه در حین یادگیری زبان برنامه نویسی Solidity و یا توسعه قرارداد های هوشمند، اصطلاح Enums به گوشتون خورده باشه و کنجکاو شده باشید، اگر علاقه دارید بیشتر در مورد Enum ها در سالیدتی بدونید،‌ تا آخر این مقاله آموزشی همراه من باشید!آرین حسینی - Arian Hosseini - مفهوم Enums در Solidity - مفهوم Enum ها در سالیدتی Enum ها چی هستند و چه کاربردی دارند؟کلمه Enum در زبان انگلیسی مخفف Enumeration هست و به زبان خیلی ساده،‌ Enum ها به شما این امکان رو میدن که برای متغیر هاتون، مقادیر از پیش تعریف شده (predefined values) ایجاد کنید،یعنی یک متغیر رو فقط محدود به داشتن یکسری مقادیر خاص و از پیش‌تعریف شده بکنید،که در نتیجه باعث جلوگیری از به وجود اومدن باگ های احتمالی در کدتون میشه و همچنین برای مدیریت خطاها و ارور ها هم بسیار کاربردی هست.به صورت فنی،‌ شما یک Enum رو تعریف میکنید و یک لیست مشخصی از مقادیری که میخواید همیشه ثابت باشه رو مینویسید که بهشون میگیم Member یا اعضای اون Enum، بعد میتونید یک variable تعریف کنید از نوع اون Enum به خصوص که ساخته بودید، درواقع data type اون متغیر رو شما به جای string, boolean و... برابر با enumی که ساخته بودید، قرار میدید و دیگه اون متغیر فقط محدود به داشتن یکی از اون Member ها یا مقادیر از پیش‌تعریف شده‌ میشه،جلوتر مثال هایی رو باهم میبینیم و کامل درک خواهید کرد، نگران نباشید!ساختار تعریف یک enum در سالیدتی به شکل زیر هست:enum &lt;enumName&gt;  { member1, member2, member3, ... }نکته: شما میتونید enum ها رو حتی خارج از بلاک کد یک contract و یا library هم تعریف کنید.همونطور که مشاهده میکنید، ساختار تعریف یک enum بسیار ساده هست، با کلمه کلیدی enum همراه با یک نام تعریف میشن و بعد داخل { ... } تمامی مقادیر دلخواه‌‌تون رو تعریف میکنید که ما به عنوان یک Member می‌شناسیم، همچنین نیازی به قراردادن سمی کالن ; هم نیست!بریم چندتا Enum واقعی رو با هم ببینیم:enum Color { BLUE, GREEN, RED }
enum LightMode { OFF, ON }
enum frenchFriesSize { LARGE, MEDIUM, SMALL }
enum Status { Finished, Pending, Failed }مثلا frenchFries (سیب زمینی سرخ کرده) رو در نظر بگیرید، اینطور تصور کنید که شما میخواید سفارش سیب‌زمینی سرخ کرده بگیرید، حالا میخواید سه تا اندازه و سایز مشخص برای french fries ها تون مشخص بکنید و اجازه ندید مشتری هر سایزی که میخواد بخره، پس شما میاید حق انتخاب و گزینه های مشتری رو محدود میکنید فقط به سه گزینه Large, Medium, Small که میتونه فقط از بین این موارد یکی رو انتخاب کنه و سفارش بده.یا مثلا به مثال دوم LightMode توجه کنید، در دنیای واقعی کلید روشن و خاموش کردن لامپ ها، ۲ حالت بیشتر نداره، یا چراغ خاموشه یا روشنه! شما نمیخواید این وسط کلی حالت دیگه هم وجود داشته باشه، درنتیجه اینجا از enum ها استفاده میکنید که میگید چراغ یا میتونه ON باشه یا OFF، حالت دیگری نداریم.اینها‌ صرفا چندتا مثال بودن که مفهوم Enums رو بهتر درک کنید.پس تا الان متوجه شدید که Enum ها صرفا یک متغیر رو محدود به داشتن یکسری مقادیر از پیش‌تعریف شده و ثابت میکنند و اون متغیر هر مقداری نمیتونه داشته باشه. (مثال لامپ ها:‌ یا ON یا OFF، تمام!)نحوه استفاده از Enum ها در سالیدتیخب بعد از اینکه شما یک enum رو تعریف کردید،‌ میخواید یک متغیر از نوع (data type) اون enum بسازید، (چون با توجه توضیحات بالا میدونید دیگه enum ها به تنهایی کار خاصی نمیکنند)همونطور که احتمالا در جریان هستید، Solidity یک زبان برنامه نویسی statically-typed هست، به این معنا که حین تعریف یک متغیر شما باید Data Type اون مقداری که قرار داخل متغیر ذخیره بشه رو از قبل تعیین کنید،‌ به طور مثال اگر قراره داخل متغیر name شما یک string ذخیره کنید، باید دیتا تایپ اون متغیر رو از قبل برابر با یک string قرار بدید؛حالا اگر شما بخواید داخل یک متغیر از مقادیر پیش‌فرض یک enum استفاده کنید،‌ قاعدتا نیاز دارید از قبل نوع اون متغیر رو برابر با نام enumی که تعریف کرده بودید، قرار بدید، به مثال زیر توجه کنید:contract Arian {
    enum Color { Red, Blue, Green }
    
    Color myFavoriteColor = Color.Blue;
}در اسمارت کانترکت بالا، من یک متغیر ساختم با نام myFavoriteColor که قرار مقدار رنگ مورد‌علاقم رو داخلشم ذخیره کنم، همچنین من از enum ها استفاده کردم چون به طور مثال داخل این کانترکت فقط میخوام همین ۳ تا رنگ موجود باشه و باهاش کار کنم (محدود کردم به استفاده از همین ۳ گزینه)حالا چطور باید به Member ها یا آیتم های یک Enum دسترسی داشت؟خیلی ساده شما فقط کافیه بعد از نام enumتون و دات (نقطه)، اسم آیتم رو بنویسید.پس من یک متغیر تعریف کردم با نام myFavoriteColor و مقدار Color.Blue رو داخلش ذخیره کردم، خب حالا آیا میتونم دیتا تایپ این متغیر رو بزارم string؟‌ یا int؟ مشخصه که نه! چرا؟ چون من یک enum داخلش ذخیره کردم پس نوع داده این متغیر باید Color باشه، دقیقا نام همون enumی که ساخته بودم.دقت کنید که Member های Enum شما نمیتونن دیتا تایپ هایی مثل string یا boolean و یا uint باشند، اگر هم چند کلمه‌ای بودن باید با underscore (_) اون هارو تعریف کنید، درغیر این صورت به ارور برمیخورید.خیلی راحت بود، نه؟!نکته: Solidity در پشت صحنه (یا به قول انگلیسی ها under the hood)، میاد و enum ها رو به unsigned integer یا uint تبدیل میکنه.جلو تر متوجه خواهید شد، این نکته یعنی چی.حالا شما میتونید به همین روش، فانکشن هایی رو تعریف کنید که با این enum ها کار میکنند، مقادیرشون رو تغییر میدن، یا return میکنند، به مثال انتخابات آمریکا توجه کنید :) https://gist.github.com/RyanHosseini/af42aa3c1ca7117183206d2edead65bc خب، یک Smart Contract ساختم با نام USAElection که میخوایم‌ داخلش کامل Enum ها رو یاد بگیریم و باهاشون حسابی کارکنیم،داخل این قرارداد هوشمند من یک enum تعریف کردم با نام Candidates که قرار لیست نامزد های انتخابی ریاست جمهوری ایالات متحده آمریکا رو داخلش از پیش‌ تعریف کنیم و به افراد رای دهنده بگیم، آقا کلا ۳ تا نفر کاندید ریاست جمهوری هستند، از بین این ۳ تا میتونی یکی رو بهش رای بدی، همینطوری نیست که بری دست یکی رو بگیری بیاری و بگی من میخوام ایشون رییس جمهور باشه، کامل جا افتاد؟ ?کاندید ها کیا هستند؟‌ ایلان ماسک، جو بایدن، دانلد ترامپنکته حاشیه‌ای: ایلان ماسک نمیتونه رئیس جمهور آمریکا بشه، به این دلیل که در آمریکا متولد نشده، حالا ما اینجا صرفا مثال آموزشی زدیم، درگیرش نشید! ?خب حالا من چند تا متغیر تعریف کردم با نام myChoice که کاندید محبوب و مدنظر من هست، AshkanChoice که کاندید دوستم اشکان، VahidChoice کاندید مدنظر وحید و ArminChoice انتخاب آرمین هست، همچنین یک currentPresident هم داریم که از نوع constant هم تعریف شده و رئیس جمهور فعلی رو شامل میشه.نکته:‌ زمانی که شما برای یک متغیر از کلمه کلیدی constant به معنای ثابت استفاده میکنید،‌ مقدار اون متغیر در ادامه کد ها و برنامه‌تون نمیتونه تغییر کنه، صرفا همون مقداری همیشه خواهد بود که اول براش تعریف کردید و در واقع همیشه ثابت هست.خیلی هم عالی، کاندید های مدنظر آرمین، اشکان و وحید رو که از قبل مشخص کردیم، سه تا فانکشن با نام های setElonMusk, setJoeBiden, setDonaldTrump هم تعریف کردم که قراره مقدار myChoice (انتخاب من) رو تغییر بدن، یعنی من هرکدوم رو call کنم، کاندید مدنظر من تغییر میکنه،مثلا اگر من تابع setElonMusk رو صدا بزنم، مقدار myChoice میشه Candidates.ELON_MUSK.همچنین همونطور که مشاهده میکنید، یک فانکشن دیگه هم وجود داره با نام setMyChoice که از شما یک id میگیره و بسته به اون id، مقدار enum متغیر myChoice رو تغییر میده، اگر صفر رو پاس بدید، myChoice میشه Joe Biden، اگر ۲ رو پاس بدید، تغییر میکنه به ایلان ماسک و به همین ترتیب، اگر هم آی دی‌ای رو پاس بدید که وجود نداره، مقدار برابر میشه با currentPresident یا رئیس جمهور فعلی که در اینجا برای مثال آقای دانلد ترامپ هست،فانکشن دیگری که ما داریم، getMyChoice هست که میبینید مقدار بازگشتیش (returns) برابر با Candidates هست، یعنی قرار یک enum با نام Candidates ریترن کنه، در واقع الان سالیدیتی، Candidates رو یک DATA TYPE می‌شناسه، شما میتونید با این نوع داده، یک متغیر تعریف کنید، یا برای یک فانکشن مشخص کنید که قرار یک مقدار از نوع Candidates برگردونه!❌  پس دقت داشته باشید در قسمت (.......) returns تابع شما به هیچ عنوان نمیتونید بنویسید &#x60;&#x60;&#x60;returns (enum)&#x60;&#x60;&#x60; و به جاش باید نام اون enum رو قرار بدید.اگر تابع getMyChoice رو کال کنید، میبینید که بهتون یک عدد برمیگردونه و نه مقدار ایلان ماسک و...، چرا؟ دلیلش چیه؟ دلیلش این هست که همونطور که بالاتر اشاره کردم، سالیدتی در پشت صحنه، enum ها رو به یک uint تبدیل میکنه،در نتیجه شما اگر مقدار myChoice رو return کنید،‌ صرفا index اون آیتم یا ممبر رو داخل enum بهتون نشون میده (دقیقا مشابه index در آرایه ها)به طور مثال، اگر مقدار Elon Musk باشه، به شما ایندکس 2 رو نشون میده، درسته؟ Joe Biden ایندکس شماره صفر هست در نتیجه بعدی 1 و ایلان ماسک میشه 2.در نهایت، داخل تابع getArminChoice که قرار کاندید مدنظر آرمین رو برگردونه هم میبینید که ما اومدیم enum رو تبدیل به یک uint کردیم و بعد return کردیم که بازم فرقی نمیکنه، چون درنهایت شما Member های اون enum رو به صورت یک uint میبینید، این رو صرفا خواستم دیده باشید.نتیجه گیری نهایی:Enum ها در سالیدتی بسیار سادست و با چندبار تمرین کردن و مثال زدن برای خودتون، قطعا به خوبی بهش مسلط خواهید شد.امیدوارم که این مقاله آموزشی بهتون در درک مفهوم Enum ها کمک کرده باشه! خوشحال میشم نظراتتون رو بدونم، قطعا این مقاله به مرور زمان به کمک شما عزیزان تکمیل تر و اشکالاتش رفع خواهد شد!مرسی از اینکه تا آخر با من همراه بودید! ☕</description>
                <category>سید آرین حسینی</category>
                <author>سید آرین حسینی</author>
                <pubDate>Sun, 15 Jan 2023 01:14:33 +0330</pubDate>
            </item>
                    <item>
                <title>مفهوم Referential Equality در React</title>
                <link>https://virgool.io/Solidity/referential-equality-in-react-qqrullbwnmtn</link>
                <description>Referential Equality چیست و چه کاربردی دارد؟ | Referential Equality در ری‌اکت | Referential Equality در React مفهوم Referential Equality در React -  آرین حسینی  - Arian Hosseiniسلام، ممکنه در حال یادگیری کاربرد های هوک useMemo, useCallback یا هوک های دیگر بوده باشید و کلمه Referential Equality به گوشتون خورده باشه، همونطور که ممکنه بدونید دومین کاربرد هوک useMemo در React همین مفهوم Referential Equality هست که در این مقاله قراره با هم بررسی کنیم؛پس اگر علاقه دارید بیشتر در مورد Referential Equality بدونید، تا آخر این مقاله همراه من باشید...قبل از اینکه بخوام در مورد این مفهوم صحبت کنم، دوست دارم یکسری مقدمه و مفاهیمی که در ادامه کار نیاز داریم بدونیم رو همینجا توضیح بدم که نیاز به مطالعه مقالات و منابع مظاعف نداشته باشید، اگر شما این مفاهیم رو میدونید، میتونید این قسمت رو Skip کنید.در ضمن این مقاله یک مقداری طولانی هست پس حتما حین خوندنش باید پر انرژی و سر حال باشید که بتونید کامل تا آخر دنبال کنید و مباحث رو درک کنید، اگر الان شرایطش رو ندارید میتونید براحتی این صفحه رو bookmark کنید و بعدا بهش مراجعه کنید. قهوه فراموش نشه :)بریم که شروع کنیم:بخش اول:‌ Primitive and Reference Data Typesدر زبان JavaScript ما دو نوع Data type داریم:1. Primitive Data types || انواع داده های اولیه2. Reference Data typesخودتون رو زیاد درگیر ترجمه فارسی این کلمات نکنید و سعی کنید به همون شکل انگلیسی اون ها رو به خاطر بسپارید.به طور کلی زمانی که شما یک متغیر در JavaScript تعریف میکنید، اون متغیر میتونه یکی از این نوع داده ها یا data type هارو داخل خودش ذخیره کنه،اگر مقداری که داخل متغیر ذخیره میکنید number, string, boolean, undefined, null یا یک symbol باشه، شما در واقع یک نوع داده Primitive یا یک Primitive Data type رو داخل اون متغیر ذخیره کردید، ولی اگر اون مقدار یک Object, Array, Function یا هر نوع داده دیگری باشه، شما در واقع یک نوع داده Reference یا Reference Data type رو ذخیره کردید. (بهتر بگم هر چیزی که از نوع Object در JavaScript هست مثل فانکشن ها و آرایه ها که میتونید با operator یا عملگر typeof اون رو چک کنید)مثال:‌const age = 20; // primitive
const name = &amp;quotArian Hosseini&amp;quot // primitive
const isLoggedIn = false; // primitive
const user = undefined; // primitive
const response = null; // primitive
const counter = Symbol(&amp;quotcounter&amp;quot); // primitive

const person = { firstName: &amp;quotArian&amp;quot  }; // reference
const coaches = [&amp;quotClarian&amp;quot,  &amp;quotMax&amp;quot]; // reference
const getSomething = () =&gt; {}; // referenceوقتی شما به کد بالا نگاه می‌کنید، خب تمامی این نوع داده هایی که در متغیر ها ذخیره شده، یک شکل به نظر میاد اما تفاوت به قول انگلیسی ها under the hood هست یا یک جورایی در پشت صحنه و در اعماق ماجرا، منظورم چیه؟! ساده تر بگم مقادیری که Primitive هستند، به شکلی همون مقدار داخل اون متغیر ذخیره میشه اما مقادیری که از نوع داده Reference هستند، آدرسشون (Memory Address) داخل اون متغیر ذخیره میشه نه خود مقدار، در واقع آدرس اون نقطه‌ای در حافظه که این مقدار داخلش ذخیره شده!یک مثال میزنم که این مورد رو خیلی بهتر درک کنید:let lastName = &amp;quotHosseini&amp;quot
let displayName = lastName;

lastName = &amp;quotNorth&amp;quot

console.log(lastName); // &amp;quotNorth&amp;quot
console.log(displayName); // &#039;Hosseini&#039;چی شد؟ در مثال بالا من یک متغیر تعریف کردم با نام lastName و مقدار &quot;Hosseini&quot; رو که یک string هست رو داخلش ذخیره کردم و بعد یک متغیر جدید ساختم با نام displayName و مقدارش رو برابر قرار دادم با مقدار متغیر lastName، خیلی ساده بود نه؟!حالا در خط بعدی اومدم و مقدار اون متغیر lastName که اول تعریف کرده بودم رو تغییر دادم به رشته عددی &quot;North&quot; (یک نام خانوادگی آمریکایی هست با اصالت British)تا اینجا احتمالا خودتون تونستید حدس بزنید که چی شد! اگر الان مقدار lastName رو لاگ بگیریم، مقداری که برای ما بر می گردونه &quot;North&quot; هست که خب طبیعی هم هست، من یک متغیر تعریف کردم و چند خط بعد یا در ادامه کد هام اومدم مقدارش رو تغییر دادم، اگر الان لاگ بگیرم، قاعدتا باید مقداری که تغییر داده بودم رو مشاهده کنم؛اما اگر displayName رو لاگ بگیرم، مقدار &quot;Hosseini&quot; رو برای من برمیگردونه! چرا؟ فکر میکنم واضح باشه، زمانی که من displayName رو برابر قرار دادم با lastName، مقدار lastName همچنان Hosseini بود پس قطعا همین مقدار داخل displayName هم ذخیره خواهد شد، حالا اینکه من بعدا در لاین های بعدی مقدار lastName رو تغییر دادم، دیگه هیچ ربطی به displayName نداره! و این دو تا کاملا مستقل از همدیگر هستند!این مثال رو که برای یک نوع داده Primitive که در اینجا string بود رو با هم دیدیم (برای تمامی Primitive Data type های دیگه هم صدق میکنه) حالا بریم یک مثال دیگه در مورد Reference data type ها داشته باشیم؛let person1 = { firstName: &amp;quotArian&amp;quot, lastName: &amp;quotHosseini&amp;quot };
let person2 = person1;

person2.lastName = &amp;quotNorth&amp;quot

console.log(person1.lastName); // North
console.log(person2.lastName); // Northنتیجه جالب شد!‌ اینطور نیست؟! چطور هر دو پراپرتی lastName برای هر دو آبجکت برابر با یک مقدار هستند؟! اجازه بدیم از اول توضیح بدم:اول اینجا من یک متغیر تعریف کردم با نام person1 که برابر با یک آبجکتی هست که شامل دو تا پراپرتی firstName و lastName میشه که مساوی با نام بنده هستند، در لاین بعدی من یک متغیر جدید ساختم با نام person2 که مقدارش رو برابر قرار دادم با مقداری که در متغیر person1 داشتم!همونطور که اوایل مقاله توضیح دادم Object ها یک نوع داده reference هستند، یعنی وقتی شما یک متغیر تعریف میکنید و مقدارش رو برابر با یک Object میذارید، اون Object شما در یک نقطه از حافظه ذخیره میشه و فقط آدرسش (Memory Address) هست که داخل متغیر ذخیره میشه، Source: Mosh Hamedani Youtube Videoکه در مثال بالا person1 صرفا حاوی آدرس نقطه‌ای از حافظه هست که اون آبجکت در اون خانه‌ی حافظه ذخیره شده و قرار داره، بهتر بگم person1 داره اشاره میکنه به آدرس نقطه‌ای از حافظه که آبجکت من در اونجا ذخیره شده!!! به طور مثال برای اینکه بهتر بتونید این مورد رو به خاطر بسپارید یک چنین چیزی رو تصور کنید (اصلا درست نیست صرفا برای اینکه راحت تر بتونید تصور کنید و این رو به خاطر بسپارید)person1 --------&gt;&gt;&gt;&gt;&gt; 962012d09b817 (مثلا فرض کنید این عبارت 962012d09b817 آدرس اون نقطه در حافظه هست)حالا این نقطه 962012d09b817 از حافظه رو اگر بهش رجوع کنیم، میبینیم که آبجکت ما اونجا هست‌ (مشابه تصویری که در بالا میبینید، x و y دو تا متغیر هستند که جفتشون اشاره میکنند به یک نقطه از Memory که آبجکت اونجا قرار داره و صرفا آدرس اون نقطه در حافظه هست که در این متغیر ها ذخیره شده)خب الان پس با این اوصاف مقدار person2 که برابر قرار داده بودم با مقدار person1 چیه؟ دقیقا! آدرس اون نقطه از حافظه که حالا مثلا در مثال ما اینجا شما اینطور تصور کنید که یک همچین آدرسی هست 962012d09b817.پس در اینجا متغیر های person1 و person2 به طور همزمان دارند به یک نقطه از حافظه اشاره میکنند! یا حاوی یک آدرس هستند که اون آدرس م ارو به اون نقطه از حافظه میبره که آبجکت ما اونجا قرار داره...به همین راحتی! پس وقتی که من در لاین بعدیperson2.lastName = &amp;quotNorth&amp;quotرو مینویسم و مقدار پراپرتی lastName متغیر person2 رو تغییر میدم، در واقع دارم مقدار پراپرتی همون آبجکتی رو تغییر میدم که person1 هم داره بهش اشاره میکنه! person1 و person2 شامل دوتا آبجکت مجزا و متفاوت نیستند! هر دو یک آبجکت هستند و این دو متغیر دارند به این تک آبجکت اشاره می‌کنند، پس فرقی نمیکنه شما از طریق person2 پراپرتی های اون آبجکت رو تغییر بدید یا از طریق person1، در هر دو حالت اون آبجکت تغییر میکنه و اگر شما person1 و person2 رو لاگ بگیرید،‌ میبینید که مقداری که جفتشون برمیگردونند، یکی هست و تفاوتی نداره. (بر خلاف چیزی که در Primitive Data Types دیدیم)مقایسه (Comparison) Primitive Data Type ها و Reference Data Type هااین قسمت بسیار مهم هست، حتما دقت کنید! اگر شما بخواهید با operator یا عملگر === که از انواع Comparison Operators در JavaScript هست دو تا متغیری که حاوی یک مقدار primitive یکسان هستند رو با هم دیگه مقایسه کنید، چه نتیجه‌ای می‌گیرید؟! برای مقادیری که از یک Reference data type یا یک نوع داده Reference هستند مثل آرایه ها چطور؟بزارید چند تا مثال بزنم!const myName = &amp;quotArian&amp;quot
const yourName = &amp;quotArian&amp;quot

console.log(myName === yourName); // trueدر این مثال من اومدم دو تا string که از انواع داده های Primitive هستند رو با هم مقایسه کردم، همونطور که میبینید به من true برگشت داده؟ چرا چون عملگر === در جاوااسکریپت primitive ها رو بر اساس value یا مقدارشون مقایسه میکنه! (Comparison by value) یعنی میگه خب من داخل myName یک string دارم که Arian هست در yourName هم یک string دارم که Arian هست، این دو تا مقدار رو با هم مقایسه میکنه و میگه بله هر دو یکسان هستند و true بر میگردونه؛حالا به این مثال توجه کنید:const BMW = {
	type: &amp;quotCompany&amp;quot,
	location: &amp;quotGermany&amp;quot,
};const MercedesBenz = {
	type: &amp;quotCompany&amp;quot,
        location: &amp;quotGermany&amp;quot,
};

console.log(BMW === MercedesBenz); // falseدر Reference ها (انواع داده های Reference مثل object ها و...) این عملگر === در جاوااسکریپت مقادیر رو بر اساس رفرنسشون (reference) یا نقطه‌ای که در حافظه هستند، مکانی که در حافظه قرار دارند با هم مقایسه میکنه! (Comparison by reference)در این مثال میتونید ببینید که من دوتا آبجکت یکسان دارم که هیچ تفاوتی باهم ندارند، تمامی پراپرتی هاشون با هم برابره اما زمانی که این دو رو با هم مقایسه میکنم، چون که جاوااسکریپت این دو رو بر اساس نقطه‌ای که در حافظه هستند با هم مقایسه میکنه، میبینه که خب آبجکت اول که در متغیر BMW هست مثلا در فلان نقطه از حافظه ذخیره شده و آدرسش یک چیزی هست اما آبجکت دوم که داخل متغیر MercedesBenz ذخیره شده در فلان نقطه دیگر از حافظه هست، پس در نتیجه با هم برابر نیستند و false.Primitive Data Types -&gt; Comparison by valueReference Data Types -&gt; Comparison by referenceدو تا آبجکت یکسان که در مکان های مختلفی از حافظه قرار دارنددر تصویر بالا مشاهده میکنید که ما دو تا آبجکت یکسان داریم، اما اگر این هارو با هم مقایسه کنیم، نتیجه false هست، دلیل رو هم که بالاتر توضیح دادم، اینکه Reference Data type ها بر اساس آدرس مکانشون در حافظه مقایسه میشن نه بر اساس مقدار یا value شون،console.log(object1 === object2); // false نتیجه:پس تنها زمانی دو تا متغیر که حاوی یک نوع مقدار Reference هستند با هم مساوی خواهند شد که هر دو به یک نقطه‌ای از حافظه اشاره کنند در غیر این صورت مساوی و برابر نیستند حتی اگر مقدارشون کاملا با هم برابر باشد. (مثال بالا در مورد پراپرتی های آبجکت ها - بر خلاف Primitive Data Types)اما متغیر هایی که حاوی یک نوع مقدار Primitive هستند، تنها زمانی با هم مساوی و برابر خواهند شد که مقدار یا value هر دو با هم کاملا برابر باشد.درست شد؟ امیدوارم که تونسته باشم به خوبی این مبحث رو بهتون انتقال بدم، اگر متوجه نشدید، بدونید قطعا من خیلی بد توضیح دادم و این مشکل شما نیست، از این بابت هم عذر میخوام.بخش دوم: به صورت کلی React چطور فرآیند re-render رو تعیین میکنه؟همونطور که میدونید، در React تنها زمانی کامپوننت رندر مجدد خواهد شد که تغییری در state یا props های اون کامپوننت به وجود بیاد، پس برای مثال اگر زمانی مقدار state یک کامپوننت تغییر کنه، React.js میاد اون کامپوننت رو re-render میکنه.برای درک بهتر به مثال زیر توجه کنید:const [name, setName] = useState(&amp;quot&amp;quot);

const handleChangeName = (newName) =&gt; {
     setName(newName);
};در مثال بالا فرض کنید من یک Event Handler دارم که هر زمان شما اون رو call کنید و اسم جدید رو به عنوان argument بهش پاس بدید، مقدار name رو در state آپدیت میکنه و name برابر میشه با نام جدیدی (newName) که در نظر گرفتید؛حالا React اینجا میاد مقدار نام جدید رو با مقدار name قبلی در state مقایسه میکنه (به واسطه الگوریتم خاص خودش که داره و البته به کمک متد Object.is) و در صورتی که اینها با هم تفاوت داشتند، re-render انجام میشه در غیر این صورت اگر برابر بودند که اتفاق خاصی نمی‌افته.گفتم که React در پروسه مقایسه کردن و الگوریتم خودش برای اینکار از built-in متد () Object.is استفاده میکنه، این متد دو تا argument قبول میکنه، این دو تا رو با هم مقایسه میکنه و یک boolean بر میگردونه که آیا با هم برابر بودند یا خیر،نکته:‌ متد Object.is با عملگر === در جاوااسکریپت یکسان نیست و یکسری تفاوت هایی با هم دارند، برای اطلاعات بیشتر میتونید این لینک رو بررسی کنید.Syntax:  Object.is(value1, value2)متد Object.is در JavaScript تعیین می کنه که آیا دو مقدار یکسان هستند یا خیر در صورتی که:هر دو مقدار undefined یا null باشند،هر دو مقدار true یا false باشند،هر دو مقدار یک string با length، ترتیب و کاراکتر های کاملا یکسان باشند،هر دو مقدار number باشند با یک مقدار یکسان یا NaNهر دو مقدار یک Object یکسان باشند که در یک نقطه از حافظه قرار دارند (بالاتر توضیح دادم)، پس React این قوانین رو برای رندر مجدد کامپوننت ها در زمانی که تغییری در state یا props ایجاد میشه، اعمال می کنه.خب این موارد رو گوشه‌ی ذهنتون داشته باشید حالا میریم سراغ مشاهده این مفهوم Referential Equality در کد و عمل!بخش سوم: Referential Equality - نحوه مقایسه در عمل!کد زیر رو در نظر بگیرید، یک کامپوننت ساده با نام App: https://gist.github.com/aryanhosseini/b6ece338d9164c70c48248c86908db46 خب همونطور که در کد بالا مشاهده می کنید، من یک state variable ساختم با نام myself که به صورت پیش فرض با یک آبجکت شامل دو پراپرتی name و age اون رو مقدار دهی کردم، در لاین بعدی یک Event handler تعریف کردم با نام changeNameToClarian که کارش اینه بیاد و پراپرتی های مقدار myself رو در state تغییر بده (بله! میدونم نباید state و props رو به صورت مستقیم تغییر بدیم، اینجا صرفا برای آموزش هست)، یک button در صفحه قرار دادم با که هر موقع کلیک شد، این فانکشن رو call میکنه و باید نام رو از Arian به Clarian تغییر بده همینطور مقدار سن رو، اگر موافق هستید بریم نتیجه رو بررسی کنیم؛خروجی مثال کد بالادر اینجا زمانی که من روی button &quot;نام من رو تغییر بده&quot; کلیک میکنم، طبق انتظاراتون باید مقدار state رو تغییر بده و رندر مجدد انجام بشه و در نهایت UI ما آپدیت بشه، اما این اتفاق نمی‌افته! چرا؟حتی اگر console رو مشاهده کنید،‌ میبینید که آبجکت myself که در لاین 9 لاگ گرفتیم رو هم با مقادیر جدید نشون میده، اما چرا این آبجکت جایگزین initial value قبلی state مون نشده و مقدار همچنان Arian و 20 هست؟!مقدار myself که در لاین 9 لاگ گرفتیم! اگر متعجب شدید که چرا کامپوننت re-render نشده، باید بگم که بهتره یک نگاهی دوباره به قوانین که متد Object.is برای مقایسه کردن داشت بندازید:5. زمانی دو Object برابر در نظر گرفته میشوند که هر دو در یک نقطه از حافظه باشند و یک Memory Address داشته باشند، در غیر اینصورت برابر نخواهند بود حتی اگر تمامی پراپرتی هاشون با هم برابر باشد.خب حالا با دونستن این مورد، میتونیم بهتر مشکل رو درک کنیم:const changeNameToClarian = () =&gt; { 
    myself.name = &amp;quotClarian&amp;quot
    myself.age = 25; 
    console.log(myself); 
    setMyself(myself);
 };در کد بالا میبینیم که مقادیر جدید که Clarian و 25 باشند به اصطلاح assign خواهند شد به عنوان مقادیر پراپرتی های آبجکت (منظور جایگزین مقادیر پیش فرض قبلی خواهند شد)، حالا زمانی که React میاد و بر اساس الگوریتم خودش به واسطه متد Object.is میخواد این دو آبجکت تغییر یافته رو با آبجکتی که به عنوان initial value ابتدا برای state تعریف شده بود، مقایسه کنه، میبینه که خب مقدار این آبجکت همچنان برابر با اون همون initial value هست و فرقی نکرده، در واقع در پشت صحنه، هر دو مقدار دارن اشاره میکنند یا به اصطلاح پوینت (point) میکنند به یک مکان در حافظه که باعث میشه در کل یکسان و مساوی تلقی بشن!!!به این فرآیند به اصطلاح Referential Equality گفته میشه ، به این دلیل که Object ها بر اساس مکان حافظه شان (Memory Location) برابر و مساوی در نظر گرفته می شوند و نه بر اساس مقادیرشان (پراپرتی ها)داخل پرانتز این رو هم بگم که این کلمه در فارسی &quot;برابری ارجاعی&quot; ترجمه شده که به نظرم بهتره معادل انگلیسی رو یاد بگیرید و زیاد خودتون رو درگیر این ترجمه ها نکنید!میدونم ممکنه یکم درکش در ابتدا سخت باشه، اما مطمئن باشید به مرور قطعا کامل درک خواهید کرد.اجازه بدید یک بار دیگه خیلی ساده و راحت توضیح میدم: مشکل ما این بود که درسته که ما اومدیم myself.name و myself.age رو تغییر دادیم، اما این تغییر باعث ایجاد آبجکت جدیدی که نمیشه و این تغییرات روی همون آبجکتی اعمال میشه که در نقطه یکسان از حافظه قرار داشت، دقیقا برابر با همون مکان آبجکتی که در state ابتدا به عنوان initial value تعریف کردیم! یعنی ما صرفا پراپرتی های اون آبجکت رو درسته در واقعیت تغییر دادیم اما متد Object.is که اینو نمیفهمه!!! این متد میگه اوکی اون آبجکت اولیه بود که داخل state به عنوان initial value ست کردیم مثلا در نقطه 5sdf4 از حافظه قرار داره، و این آبجکت جدید هم که اومدیم پراپرتی هاش رو در متد changeNameToClarian ویرایش کردیم در نقطه 5sdf4 از حافظه قرار داره، خب پس این متد Object.is خیلی شیرین به این نتیجه میرسه که این دوتا آبجکت هیچ تفاوتی با هم ندارند و به React میگه که رندر مجدد بی رندر مجدد و از این خبرا اینجا نیست...! درسته شد؟! حالا راه حلش چیه؟خیلی ساده باید کاری کنیم که یک آبجکت جدید ساخته باشه که Memory Address‌اش برابر با Memory Address اون آبجکت اولیه در state نباشه! همین! حالا یکی از روش ها به این صورت هست:const changeNameToClarian = () =&gt; {
    myself.name = &amp;quotClarian&amp;quot
    myself.age = 25;
    console.log(myself);
    setMyself({ ...myself });
};مشاهده میکنید که ما یک آبجکت جدید به setMyself پاس دادیم که در یک نقطه دیگری از حافظه قرار داره و با spread operator اومدیم پراپرتی های آبجکت myself که تغییرش داده بودیم رو استخراج کردیم و به عنوان پراپرتی های این آبجکت جدید ست کردیم و عملا دیگه خبری از Referential Equality اینجا نیست چون ما دو تا آبجکت مستقل از هم داریم که الان React میتونه این رو متوجه بشه.مشخصات با موفقیت تغییر کرد و رندر مجدد انجام شد! یکی از دلایلی که state رو نباید به صورت مستقیم ویرایش کنیم، همین هست چون React دیگه کنترل وضعیت از دستش خارج میشه و دیگه نمیتونه پیگیر تغییرات state باشه که بعد بخواد re-render انجام بده.نتیجه گیری نهایی:این بسیار مهم هست که ما بدونیم آبجکت ها چطور و کجا ذخیره میشن و اینکه React چطور میاد مشخص میکنه که الان باید این کامیپوننت re-render بشه یا نه، بنابراین، در مواردی که کامپوننت re-render نمیشن در زمانیکه که state شون تغییر کرده، یک راه حل این هست که مطمئن بشیم Object ها با هم برابر نیستند (یعنی هر دو آبجکت در نقاط مختلفی از حافظه قرار دارند)، این مورد از به وجود اومدن یکسری باگ های احتمالی در کد جلوگیری میکنه و در روند توسعه اپلیکیشن به ما کمک میکنه.خب امیدوارم که این مقاله تونسته باشه کمکتون کنه، میدونم خیلی جاهاش ممکنه براتون گنگ بوده باشه یا اشکلاتی درش وجود داشته باشه چون یک مقداری توضیح دادنش توی متن برام سخت بود، مخصوصا اینکه این اولین مقاله‌ای هست که منتشر میکنم علاوه بر اینکه خیلی طولانی هم شد، حتما این مقاله رو با کمک شما عزیزان آپدیت خواهم کرد و اشکالاتش رو به مرور برطرف میکنم، خوشحال میشم نظراتتون رو بدونم، اگر متوجه اشکالی شدید یا قسمتی که به نظرتون خوبه توضیح نداده بودم، حتما اشاره کنید که اصلاحش کنم! مرسی از اینکه تا آخر با من همراه بودید!منابع:منبع ۱ - منبع ۲ - منبع ۳ - منبع ۴ - منبع ۵ - منبع ۶ - منبع ۷</description>
                <category>سید آرین حسینی</category>
                <author>سید آرین حسینی</author>
                <pubDate>Sat, 15 Oct 2022 22:31:32 +0330</pubDate>
            </item>
            </channel>
</rss>