<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Mohammad Bohluli</title>
        <link>https://virgool.io/feed/@MohammadBohluli</link>
        <description>علاقمند به تکونولوژی و هرچی که بهش مربوطه،
کانال تلگرام LearnByLearn@</description>
        <language>fa</language>
        <pubDate>2026-06-16 06:22:19</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2458895/avatar/5FAYGS.jpg?height=120&amp;width=120</url>
            <title>Mohammad Bohluli</title>
            <link>https://virgool.io/@MohammadBohluli</link>
        </image>

                    <item>
                <title>مسیج چه بروکری ؟!</title>
                <link>https://virgool.io/@MohammadBohluli/%D9%85%D8%B3%DB%8C%D8%AC-%DA%86%D9%87-%D8%A8%D8%B1%D9%88%DA%A9%D8%B1%DB%8C-gxlzbgglktvv</link>
                <description>سلام سلام، توی این مقاله میخوام هر آنچه که نیازه راجع به مسیج بروکر ها(بیشتر rabbitMQ) بنویسم تا درک خوبی از علت وجودشون بدونیم.اما برای درک بروکر ها بهتر که قبلش با معماری هایی مثل monolith و microservice آشنا بشیم.البته خود این دو مبحث کلی میشه روشون صحبت کرد ولی خب اینجا ما یه گریزی بهشون میزنیمدقت کنید که مسیج بروکری که ما داریم روش حرف میزنیم به صورت پیشفرض rabbitMQ هستش و ممکنه یک سری جاها توی نحوه کارکرد با بقیه بروکر ها(نه خیلی) فرق کنه✅ معماری مونولیت و میکروسرویسبا یه مثال توی دنیای واقعی شروعش کنیم، توی ذهنتون یه آشپزخونه رو درنظر بگیرید:معماری مونولیت 👈 اگه همه چیز توسط یک آشپزخونه واحد انجام بشه؛ از پخت غذا گرفته تا پذیرش سفارش و شستن ظرف‌ها و خلاصه همه چی. به این میگن معماری مونولیت که اگ یک نفر مریض بشه یا آشپزخونه دچار مشکل بشه، کل رستوران به فنا میره. پسسس توی این نوع معماری، تمام بخش‌های نرم‌افزار (مثل بخش‌های مربوط به احرازهویت، مدیریت کاربران، پایگاه داده یا ....) به صورت یکپارچه و در قالب یک پروژه بزرگ نوشته می‌شه. این بخش‌هایی که نام بردیم توی یک سرور اجرا میشه و همشون در قالب یک سورس کد بزرگ کار میکنن.معماری میکروسرویس👈 حالا همون آشپزخونه رو بازم تو ذهنت داشته باش ولی اینبار بیاییم آشپزخونه رو غرفه غرفه(تیم) کنیم و هر غرفه مسئول یه کار خاصی بشه مثلا یک تیم فقط پخت غذا رو انجام بده، یک تیم فقط پذیرش سفارش، و یک تیم فقط نظافت رو انجام بده. یعنی هر بخش مستقل میشه و اگر یک بخش دچار مشکل بشه، بقیه بخش‌ها می‌تونن همچنان به کار خودشون ادامه بدن. پسسس توی این نوع معماری، سیستم ما به مجموعه‌ای از سرویس‌های کوچک و مستقل تقسیم می‌شه که هر سرویس وظیفه خاص خودشو داره.اینکه کدوم خوبه و مزیت و معایبشون چیه رو کاری نداریم چون خودش کامل یه مقاله جدا میطلبه، فقط بدونیم چی هستن کفایت میکنه✅ دو نوع ارتباط میان میکروسرویس هاحالا این سرویس هایی که توی این معماری داریم باید یه طوری بتونن باهم ارتباط برقرار کنن یا نه؟ ما به دو روش میتونیم میون این سرویس ها ارتباط برقرار کنیم یکی sync و یکی asyncتوی روش sync از Rest API و HTTP استفاده میکنیم. دقیقا عین همون درخواست هایی که به سایت میزنیم ولی اینجا فرقش اینه دوتا سرویس دارن به هم درخواست میزنن پس یعنی توی این روش از زمانی که request ارسال میشه تا زمانی که  response اون دریافت میشه سیستم در حالت انتظار میمونه.حالا توی روش async ما میتونیم درخواست خودمون رو برای سرویس موردنظر ارسال کنیم و برعکس sync دیگه منتظر پاسخ اون نمونیم. حالا که مستقیم سرویس ها برای هم پیام ارسال نمیکنن پس چطوری اینا باهم حرف میزنن ؟؟ و این جا همون قسمتی هستش که message broker ها وارد داستان میشن و شاعر میگه : من مسیج بروکر هستم، نمی‌گذارم سرویس ها باهم قهر کنن!✅ مسیج بروکر ها چی هستنمسیج بروکر یک‌لایه ارتباط بین سرویس‌ها هست که اگر هرکدوم از سرویس‌ها بخوان پیامی برای سرویس دیگه بفرستن پیام خودشون رو روی Message Broker می‌فرستن و گیرنده، پیام خودشو  از روی Message Broker برمیداره.توی بروکر ها به فرستنده میگیم publisher یا producer و به گیرنده میگیم consumer یا subscriberبا استفاده از مسیج بروکر ها در جای درست خودش، اپلیکیشنمون loosely couple میشه یعنی سرویس هامون کمتر به هم وابسته میشن✅ مسیج بروکر ها چطور کار میکننپابلیشرها وقتی یک message میفرستن سمت بروکر، بروکر از طریق کامپوننتی به اسم exchange اون پیام رو میگیره فعلا exchange رو مثل یک router در نظر بگیر که پیام تولید شده رو مسیریابی میکنه به کجا برسه(جلوتر دقیق توضیحش میدم) خب این آقا یا خانم exchange پیام رو مستقیم و دودستی نمیده به گیرنده که!! بلکه قبلش میفرستتش به message queue یعنی پیام هامون وارد یک صف میشن و هر دریافت کننده صف خودشو داره و پیام اینطوری میرسه دست دریافت کننده خودش ، حالا دریافت کننده وقتی پیام رو گرفت و کارش رو با موفقیت تموم کرد اون پیام از صف پاک میشه دقیقا مثل تصویر زیر:✅ ا Exchange ها چی هستن و انواع شون مسئول این هستن که اون message رو طبق rule هایی که دارن مسیردهی کنن تا برسن به مقصد و چندین نوع exchange داریم که اون سه تا مهمشو من میگم:ا Direct Exchange 👈 در این نوع، پیام‌ها بر اساس کلید مسیریابی (Routing Key) دقیقاً به Queueهایی هدایت میشن که همون کلید رو دارن.پس کلید مسیریابی پیام باید دقیقاً با کلید Queue مطابقت داشته باشه. برای کجاها مناسبه ؟ اونجاهایی که پیام‌ها فقط باید به یک Queue خاص ارسال بشن ا Topic Exchange 👈 در این نوع، پیام‌ها بر اساس یک الگو (Pattern) در Routing Key به Queueهایی هدایت میشن که کلیدشوم با الگوی پیام تطابق داره. مثلا توی سناریوهایی لازمه که نیاز به مسیریابی بر اساس دسته‌بندی‌های پیچیده‌تر دارن.ا Fanout Exchange 👈 تقریبا مثل Topic هستش با این تفاوت که دیگه طبق الگو پیام ها مسیر دهی نمیشن بلکه بدون توجه به کلید مسیریابی به تمام Queueهای متصل به این Exchange ارسال میشن.توی عکس اگه دقت کنید یه کلمه هست به اسم binding، درواقع بایندینگ فرآیندی هستش که توی اون ارتباط بین یک Exchange و یک Queue تعریف میشه. پس این ارتباطه که مشخص میکنه  چه پیام‌هایی از Exchange به Queue هدایت بشن.✅ دو الگوی (pattern) مهم در message brokersالگوی Point To Point 👈 توی این الگو یک رابطه یک به یک بینsender و receiver وجود داره و message فقط یکبار توسط دریافت کننده consume یا استفاده میشه. خب شاید بگی این شد همون rest api که؟!!! دقت کن که تفاوتش با Rest اینه که بروکر تضمین میکنه consumer حتما و حتما پیام رو دریافت کنه حتی اگه آفلاین باشه، منتظر آنلاین شدن اون میشه تا مطمعن بشه پیام به دستش میرسهالگوی PUB/SUB👈 توی این الگو یک publisher پیام رو به چندین consumer میفرسته (حالا یا topic یا fanout) در واقع توی exchange از اون message کپی میگیره و میفرسته . دقت کنیم که فرستنده و گیرنده از هم اصلا خبر ندارند و براشونم مهم نیستطبیعتا وقتی نیاز داری یک پیام به چندین سرویس یا اپلیکیشن ارسال بشه از pub/sub استفاده کن و وقتی هر پیام فقط باید توسط یک سرویس پردازش بشه هم از point to point.امیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود تا بعد ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Wed, 25 Dec 2024 23:58:26 +0330</pubDate>
            </item>
                    <item>
                <title>تکه‌تکه، اما قوی‌:Sharding، Partitioning و Replication(قسمت آخر از مفاهیم دیتابیس)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%AA%DA%A9%D9%87-%D8%AA%DA%A9%D9%87-%D8%A7%D9%85%D8%A7-%D9%82%D9%88%DB%8C-sharding-partitioning-%D9%88-replication%D9%82%D8%B3%D9%85%D8%AA-%D8%A2%D8%AE%D8%B1-%D8%A7%D8%B2-%D9%85%D9%81%D8%A7%D9%87%DB%8C%D9%85-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-if7lvhwkjmnw</link>
                <description>به قسمت آخر از سری مجموعه مفاهیم دیتابیس خوش اومدی، توی این قسمت میخواییم هرچی جلو دستمون میاد رو تیکه تیکه کنیم تا قدرت واقعی دیتابیس هارو بهتر درک کنیم. دقت کنید که توی این سری مجموعه ما با انواع مفاهیم دیتابیس آشنا میشیم و کاری با کد زدن و نوع خاصی از دیتابیسا ها نداریمهمچنین قسمت قبل رو میتونید از لینک زیر 👇بخونید:اسید: این بار نه شیمی، بلکه دیتابیس!(قسمت پنجم از مفاهیم دیتابیس)✅ همانند سازی(Replication) چیه ؟؟؟اگه بخواییم یه تعریف کتابی راجع بهش بگیم میشه این: فرآیندی است که طی آن داده‌ها از یک پایگاه داده به یک یا چند نسخه دیگر کپی و توزیع می‌شوند. این روش برای افزایش دسترس‌پذیری(availability)، تحمل خطا(fault tolerance) و اطمینان از بازیابی داده‌ها(recovery) در صورت خرابی به کار می‌رود.فرض کنیم یک فروشگاه آنلاین داریم و اطلاعات محصولاتمون توی یک دیتابیس ذخیره شده. حالا اگه سرور اصلیمون به هر دلیلی بره به فنا، فروشگاهمون از کار می‌افته.حالا اگه این فروشگاه اونقدری بزرگ باشه مثل دیجی کالا خب هر یک دقیقه اشم میلیون ها ضرره. با Replication میتونیم این مشکل رو به راحتی مدیریت کنیم، بدین شکل که یک یا چند نسخه از دیتابیسمون رو توی سرورهای دیگه ذخیره کنیم. حالا اگه سرور اصلی خراب بشه، کاربران همچنان می‌تونن از نسخه‌های کپی استفاده کنن.توی ریپلیکیشن به سرور اصلی میگیم master و به فرعی ها میگیم slaveحالا مزیت هاش چیه:در صورت خرابی سرور اصلی، سرورهای دیگه می‌تونن جایگزین بشن.توزیع بار خواندن(Read) و نوشتن(Write) بین سرورها.نسخه‌های کپی داده‌ها امکان بازیابی سریع‌تر رو فراهم می‌کنن.کاربران می‌تونن به نزدیک‌ترین سرور جغرافیایی متصل بشن.دو نوع اصلی Replication داریم :ریپلیکیشن همزمان(Synchronous) 👈 در ریپلیکیشن همزمان، ایجاد کپی های دیتا به صورت بلادرنگ انجام می‌شه یعنی چی؟ یعنی بلافاصله که داده ها روی سرور اصلی(master) نشست همون لحظه عملیات Replica توی سرور های فرعی(slave) انجام میشه و در نتیجه روش گرونی هستش و پهنای باند زیادی لازم داره اما یه خوبی که داره اینه که هنگام Disaster Recovery بسیار قابل اعتماد است چون بلافاصله داده ها دارن نوشته میشن مثلا برای داده های بانکی که حساسیت کار بالاس میتونه این نوع ریپلیکیشن مناسب باشه.ریپلیکیشن غیرهمزمان(Asynchronous) 👈 کپی دیتا در ریپلیکیشن غیرهمزمان، برخلاف همزمان، در زمان های معین شده انجام می‌شه یعنی داده ابتدا روی سرور اصلی میشینه و بعد طبق زمان معینی توی سرور های فرعی کپی میشه. مثلا میتونیم تعیین کنیم که چون از 12 شب تا 6 صبح فشار رو دیتابیس و سرورامون کمتره اون موقع عملیات ریپلیکیشن انجام بشه. خب طبیعتا برای برنامه هایی خوبه که Read کردن دیتا مهمتر از Write کردن دیتا هستش(چون بلادرنگ نیست) و برای پشتیبان گیری مناسب تره.انواع دیگه هم هست که اگه بخوام توضیح بدم مقاله زیاد میشه اما اسماشونو میگم که سرچشون کنید: single-master Replication و  multi-master Replication و chain Replication و geo Replication✅ خرد کردن(Sharding) و پارتیشن(Partition) چیه ؟؟؟این دوتارو کنار هم توضیح بدم بهتر جا میوفته اما قبلش باید با دو مفهوم مقیاس پذیری عمودی و افقی آشنا بشنید:توی مقیاس پذیری عمودی(Vertical) یعنی با افزایش بار روی اپلیکیشنمون ما سرور هامون رو قوی تر کنیم مثلا رم بیشتر بخریم یا سی پی یو رو قوی تر کنیم اما توی توی مقیاس پذیری افقی(Horizontal) به جای اینکه سرور رو قوی تر کنیم بیایم تعداد سرور ها رو بیشتر کنیم عکس توی این مقاله هم ببینید بد نیستشاردینگ یا Sharding 👈 یک روش برای تقسیم‌بندی داده‌ها توی دیتابیس هست، به‌طوری‌که هر بخش از داده‌ها (یا شارد) در یک سرور مجزا ذخیره بشه. این تکنیک برای مقیاس‌پذیری افقی به کار می‌ره یعنی برای scale کردن بیاییم هی سرور دیتابیسی اضاف کنیم. همچنین به پایگاه دادمون امکان مدیریت بهتر حجم زیاد داده‌ها و درخواست‌ها رو می‌ده.شاردینگ انواع مختلفی داره مثلا میتونه بر اساس جغرافیا باشه یعنی کاربرای توی آمریکا به اون شاردی متصل بشن که نزدیک اوناس و کاربرای آسیا به شارد نزدیک آسیا متصل بشن یا مثلا اگه از نوع range باشه، تعیین میکنیم که کاربرا هایی که ID شون از 1 تا 90000 هست توی شارد یک ذخیره بشن و از 90000 تا 200000 توی شارد دوپارتیشن یا Partition👈 فرآیندی که طی آن داده‌های یک جدول به چندین بخش یا پارتیشن تقسیم میشن. این پارتیشن‌ها معمولاً در یک پایگاه داده و روی یک سرور قرار دارند(برعکس شاردینگ که روی چند سرور بود) و برای مدیریت بهتر داده‌ها و بهبود عملکرد دیتابیسمون استفاده میشن. در واقع پارتیشن بندی مقیاس پذیری عمودی رو توی دیتابیس برامون به همراه میاره✅ چه موقع از کدوم استفاده کنیم ؟؟؟معمولا زمانی از پارتیشن استفاده میکنیم که:حجم زیادی داده در یک جدول دارید، اما ترافیک پایگاه داده به‌طور کلی قابل مدیریت است.نیاز به کاهش زمان اجرای کوئری‌ها روی جداول بزرگ دارید.پایگاه داده شما در یک سرور قرار دارد و نیازی به توزیع بین چند سرور ندارید.معمولا زمانی از شاردینگ استفاده میکنیم که:حجم داده‌ها یا ترافیک پایگاه داده به حدی است که یک سرور نمی‌تواند آن را مدیریت کند.کاربران در مناطق جغرافیایی مختلف هستند و می‌خواهید تأخیر (Latency) را کاهش دهید.نیاز به مقیاس‌پذیری افقی دارید تا با افزایش تعداد کاربران یا داده‌ها، سرورهای جدید اضافه کنید.چرا میگم معمولا؟؟؟ چون تو دنیایی نرم افزار همه چیز همه جا درست نیست و قطعا وابسته به نوع کار شما و پروژتون بستگی داره یا به قول خارجکیا trade offامیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود تا بعد ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 06 Dec 2024 13:29:57 +0330</pubDate>
            </item>
                    <item>
                <title>اسید: این بار نه شیمی، بلکه دیتابیس!(قسمت پنجم از مفاهیم دیتابیس)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%A7%D8%B3%DB%8C%D8%AF-%D8%A7%DB%8C%D9%86-%D8%A8%D8%A7%D8%B1-%D9%86%D9%87-%D8%B4%DB%8C%D9%85%DB%8C-%D8%A8%D9%84%DA%A9%D9%87-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85-%D8%A7%D8%B2-%D9%85%D9%81%D8%A7%D9%87%DB%8C%D9%85-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-inyug5w23ere</link>
                <description>به قسمت پنجم از سری مجموعه مفاهیم دیتابیس خوش اومدی، توی این قسمت میخواییم شیمی ها رو بریزیم تو دیتابیسا تا اسیدی بشن. دقت کنید که توی این سری مجموعه ما با انواع مفاهیم دیتابیس آشنا میشیم و کاری با کد زدن و نوع خاصی از دیتابیسا ها نداریمهمچنین قسمت قبل رو میتونید از لینک زیر 👇بخونید:نرمال‌سازی دیتابیس: از آشفتگی تا آسودگی در چند مرحله ساده(قسمت چهارم از مفاهیم دیتابیس)✅ تراکنش(Transaction) چیه ؟؟؟قبل اینکه بریم ببینیم اسید(ACID) چیه باید با مفهوم تراکنش یا همون Transaction آشنا بشیممجموعه‌ای از عملیات های پایگاه داده‌ است که یا بایستی به طور کامل انجام بشه یا در صورت بروز مشکل وضعیت به حالت قبلی برگردونده بشه.✅ اصل اول اتمیک بودن (Atomic)این اصل میگه یک تراکنش باید به صورت کامل انجام بشه یا اصلا انجام نشه. یعنی یا همه یا هیچ و اگر بخشی از تراکنش با خطا مواجه شد، کل تراکنش لغو میشه و تغییرات Rollback میشنفرض کنید 100 تومن پول از حساب A میخواییم کارت به کارت کنیم به حساب B خب اول باید 100 تومن از حساب A برداشت بشه و به حساب B واریز بشه یعنی این کارت به کارت طی دومرحله انجام میشهحالا اگه از حساب A برداشت شد و یه مشکلی پیش اومد به حساب B نرفت چی؟یعنی پول ما رو هوا میمونه دیگه و این خیلی بدهاصل اتمیک میگه اگه این مشکل اتفاق افتاد باید پول برگردونده بشه به حساب A✅ اصل دوم یکپارچگی (Consistency)این اصل میگه تراکنش باید دیتابیس را از یک وضعیت معتبر به وضعیت معتبر دیگری منتقل کنه. یعنی هیچوقت دیتابیس نباید در وضعیت نامعتبر قرار بگیره.بازم با مثال قبلی توضیحش میدم، ببینید جمع موجودی حساب A و B قبل و بعد از ترنزکشن(کارت به کارت کردنمون) باید برابر باشه. مثلا اگه 100 تومن از حساب A برداشت بشه و به حساب B واریز بشه، مجموع موجودی حساب‌ها نباید تغییری کنه. یعنی حساب ها باید وضعیت معتبر خودشون رو حفظ کنن✅ اصل سوم ایزوله بودن (Isolation)این اصل میگه تراکنش ها باید به گونه‌ای اجرا بشن که به نظر برسه هر تراکنش به صورت مستقل انجام می‌شه، حتی اگر همزمان با ترنزکشن‌های دیگه اجرا بشه. این ویژگی مانع از اثرگذاری منفی ترنزکشن‌ها روی همدیگه میشه.ببینید مثلا اگه کاربر اول ۵۰ تومان برداشت کنه و کاربر دوم هم همزمان بخواهد برداشت کند(هردو از یک حساب)، نباید کاربر دوم قبل از به‌روزرسانی دیتابیس توسط کاربر اول، به موجودی قدیمی دسترسی داشته باشه. چون مثلا موجودی حساب کلا 50 تومنه هم کاربر اول 50 تومن رو برداشت کنه هم دوم !!!! نمیشه کهاین ایزولیشن رو میتونید توی سفارشات هم ببینید اونجا که از یک محصول مثلا یه دونه موجوده بعد دونفر همزمان اون یه دونه رو بخرن که خب اگه ازولیشن رعایت نشه ممکنه مشکل به وجود بیاد✅ اصل چهارم پایداری (Durability)و در آخر هم این اصل میگه پس از تکمیل موفقیت‌آمیز یک تراکنش، تغییرات آن باید دائمی باشن و حتی در صورت خرابی سیستم هم از بین نرن. یعنی یهو برق رفت همه چی نره باد فنامثلا در یه سیستم بانکی، اگر بعد از واریز پول به حساب B سیستم خراب شد، باید مطمئن باشیم که مبلغ واریز‌شده همچنان در حساب B موجوده.✅ حالا اگه ایزولیشن نباشه چی میشه ؟؟؟ممکنه این سه مشکل به وجود بیان که خلاصه وار توضیحشون میدم:مشکل Dirty Read 👈 وقتی یک تراکنش، داده‌ای رو که توسط تراکنش دیگری تغییر یافته اما هنوز نهایی نشده (Commit نشده) است، بخونه. اگر تراکنش اول تغییرات خود را Rollback کند، تراکنش دوم به داده‌های نامعتبر دسترسی پیدا کرده و حالا بیا و درستش کن.مشکل non-Repeatable Read 👈 وقتی یک تراکنش در طول اجرای خود، دوبار یک مقدار رو بخونه و به دلیل تغییر داده توسط تراکنش دیگری، هر بار مقدار متفاوتی ببیند.مشکل Phantom Read 👈 وقتی یک تراکنش چند بار یک کوئری رو اجرا کنه و هر بار تعداد نتایج متفاوتی دریافت کنه، به دلیل اینکه تراکنش دیگری در این بین داده‌ها رو اضافه یا حذف کرده.✅ چهار سطح ایزوله سازی در دیتابیساینکه کدوم از این چهارتا رو کی و کجا باید استفاده کنیم وابسته به نوع دیزاین و پروژتون دارهسطح read uncommited 👈 در این سطح، یک تراکنش می‌تونه داده‌هایی رو بخونه که توسط تراکنش دیگری تغییر پیدا کرده اما هنوز Commit نشده‌(یعنی هنوز تو دیتابیس ننشسته).سطح read commited 👈 یک تراکنش فقط می‌تونه داده‌هایی را بخونه که توسط تراکنش های دیگه Commit شده‌اند.سطح repeatable read 👈 یک تراکنش تضمین می‌کنه که داده‌های خوانده‌شده در طول تراکنش تغییر نخواهند کرد.سطح serializable 👈 بالاترین سطح ایزوله‌سازی که تضمین می‌کنه تراکنش ها به گونه‌ای اجرا بشن که انگار به صورت سریالی و پشت‌سرهم اجرا شده‌اند. توی این سطح هیچکدوم از اون سه مشکل بالا رو نداریم.امیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود تا قسمت بعدی(که قسمت آخرمونه) ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Wed, 20 Nov 2024 23:20:09 +0330</pubDate>
            </item>
                    <item>
                <title>نرمال‌سازی دیتابیس: از آشفتگی تا آسودگی در چند مرحله ساده(قسمت چهارم از مفاهیم دیتابیس)</title>
                <link>https://virgool.io/@MohammadBohluli/%D9%86%D8%B1%D9%85%D8%A7%D9%84-%D8%B3%D8%A7%D8%B2%DB%8C-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D8%A7%D8%B2-%D8%A2%D8%B4%D9%81%D8%AA%DA%AF%DB%8C-%D8%AA%D8%A7-%D8%A2%D8%B3%D9%88%D8%AF%DA%AF%DB%8C-%D8%AF%D8%B1-%DA%86%D9%86%D8%AF-%D9%85%D8%B1%D8%AD%D9%84%D9%87-%D8%B3%D8%A7%D8%AF%D9%87%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-%D8%A7%D8%B2-%D9%85%D9%81%D8%A7%D9%87%DB%8C%D9%85-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-i0jmvpyv9hzp</link>
                <description>به قسمت چهارم از سری مجموعه مفاهیم دیتابیس خوش اومدی، توی این قسمت میخواییم رفتار نرمالی با دیتابیس داشته باشیم و از آشفتگی داده ها نجاتش بدیم. دقت کنید که توی این سری مجموعه ما با انواع مفاهیم دیتابیس آشنا میشیم و کاری با کد زدن و نوع خاصی از دیتابیسا ها نداریمهمچنین قسمت قبل رو میتونید از لینک زیر 👇بخونید:دیتابیس بدون ایندکس، مثل کتابخانه بدون فهرست! (قسمت سوم از مفاهیم دیتابیس)✅ نرمالایز(Normalize) کردن چیه ؟؟؟اول بیاییم تعریف ویکی پدیا رو ببینیم که چی میگه؟ یکی از اصول علم پایگاه داده ها از بین بردن افزونگی است. افزونگی به این معناست یک داده خاص در چند محل مختلف پایگاه ذخیره شود.اجازه بدین یه مثال بزنم: فرض کنیم یک کمد پر از لباس داریم و این لباس هارو بدون هیچ نظم و ترتیبی چیدیم مثلا شلوارا و پیرهن ها و جورابا رو همه با هم توی یک جا چیدیم. حالا اگه بخواییم دنبال یه پیرهن خاص بگردیم مجبوریم کللل لباس هارو مثل شلوارو جوراب ها رو هم بگردیم (به این میگن افزونگی یعنی یه چیز یا یه کار مازاد و اضافه داریم انجام میدیم )اما اگه هر لباس رو  به صورت دسته بندی توی یک کمد بزاریم چی ؟  مثلاً تی‌شرت‌ها در یک قفسه، شلوارها در قفسه‌ای دیگه، و لباس‌ زمستونی ها یه جا دیگه و ... به نظرتون پیدا کردن لباس مورد نظرمون سریع‌تر و آسون تر نمیشه ؟نرمال‌سازی دیتابیس هم همین کار رو انجام میده: داده‌ها رو طوری سازماندهی می‌کنه که اطلاعات مرتبط با هم در جداول جداگونه قرار بگیرن و نیازی به تکرار اضافی نباشه. این کار از تکرار داده‌ها جلوگیری می‌کنه، دسترسی به داده‌ها رو سریع‌تر می‌کنه، و مدیریت اطلاعات رو ساده‌تر می‌کنه.نرمال سازی معمولا 5 سطح داره که تا سطح سه(بازم معمولا) کفایت میکنه این سطوح عبارتند از: BCNF - 4NF - 3NF - 2NF - 1NF✅ سطح اول نرمالایز(1NF):جدولی سطح اول نرمالایز محسوب میشه که:اول اینکه محتویات هر ستون دارای یک مقدار مشخص باشه یعنی اتمیک(atomic) باشه و داده ها تکرار نشن. یعنی چی میگی اتمیک باشه مگه شیمی داری درس میدی ؟ فرض کن یه جدول user داری و یکی از ستون هات آدرس کاربر رو ذخیره میکنه، حالا اگه بیایی آدرس کاربری مثل کاربر محمد رو اینطوری ذخیره کنی iran-tehran-tajrish داری خودتو بدبخت میکنی، چون این ستونت اتمیک نیست و دارای افزونگی داده هست و  بعدن بخوایی توی آدرس سرچ بزنی باید بدبختی بکشی و پرفورمنس پایین میادراه حل چیه ؟ بیا یه جدول به اسم address درست کن و آدرس هر کاربر رو به صورت تفکیک شده و تمیز که شامل چند ستون مثل country - city - street رو توش ذخیره کن  وبا یه کلید یه جدول user وصلش کن اینطوری هم سرچ کردن آسون میشه هم وقتی کاربر ادرسش تغییر کرد یکجا تغییر میکنهدوم اینکه آقا داده ها تکرار نشن یعنی یک کاربر ستونی به اسم course داره و کورس های متفاوتی مثل کورس ریاضی - شیمی - فیزیک داریم خب برای هر کاربر هی باید اینارو تکرار کنیم مثلا کاربر رضا کورس شیمی رو شرکت کرده باشه بنویسیم شیمی کاربر محمدم باز بنویسیم شیمی یعنی هی داریم این شیمی رو تکرار میکنیمُ اینطوری بخوایی شیمی رو اسمشو عوض کنی از هزار جا باید تغییر بدی و کلی پرفورمنس میاد پایینراه حل ؟؟؟ مثل مثال آدرس یه جدول دیگه میسازیم و کورس هارو توی اون میزاریم و با کلید خارجی به جدول user متصلش میکنیم و اگرم بخواییم تغییری بدیم فقط یک جا تغییر میدیمسوم اینکه هر جدول حتما یه کلیداصلی برای شناسایی داشته باشه که خب این دیگه معلومه نیاز به توضیح نداره توی این لینک حسابی توضیح دادیم✅ سطح دوم نرمالایز(2NF):اول اینکه جدول باید سطح اول رو رعایت یا پاس کرده باشه دوم اینکه همه ستون‌های غیراصلی کاملاً به کلید اصلی وابسته باشن. یعنی مثلا یک جدول order داریم که این ستون هارو دارهOrderID             |        CustomerID           |         Address  
      1                  |               101                   |          Tehran
      2                  |               101                   |          Tehran
      3                  |               102                   |           Shirazدر واقع جدول order باید اطلاعاتی از سفارشاتمون در اختیارمون بده نه آدرس کاربر پس  دلیلی نداره که ستون address توی جدول order باشه و چون اصلا ربطی به order نداره و ذره ای بهش وابسته نیست پس کجا بزاریمش آدرس رو ؟ هیچ جا، address باید متعلق به جدول user باشه✅ سطح سوم نرمالایز(3NF):اول اینکه جدول باید سطح دوم و اول رو رعایت یا پاس کرده باشهدوم اینکه هیچ‌گونه وابستگی بین ستون‌های غیراصلی وجود نداشته باشه. به عبارت دیگه، ستون‌های غیراصلی نباید به غیر از کلید اصلی به یکدیگر وابسته باشن. یعنی ZipCode وابسته به Cityعه و ممکنه توی بروزرسانی یا حذف مشکل ایجاد کنه(مثلا City نباشه ولی ZipCode باشه خب خیلی ناجوره) پس چه کنیم ؟ یه جدول درست کنیم به اسم City و این دوتا(City , ZipCode ) رو توش بزاریمOrderID       |       CustomerID       |       City              |       ZipCode
    1              |            101                 |     Tehran          |         12345
    2              |            102                 |     Shiraz           |         54321✅ آیا همیشه و همیشه نرمالایز خوبه بدی نداره ؟همون طور که توی هر مقاله میگم توی مهندسی نرم افزار همه چیز trade off هست و نمیشه یه نسخه برای همه چی پیچیده نرمالایز کردن هم با خوبی هایی که داره بدی هایی هم به همراه میارهافزایش پیچیدگی کوئری‌ها 👈 به دلیل اینکه داده‌ها به جداول مختلف تقسیم می‌شن، کوئری‌ها برای بازیابی اطلاعات ممکنه پیچیده‌تر بشه.کاهش کارایی در خواندن داده‌ها 👈 در برخی از کاربردها که نیاز به بازیابی سریع داده‌ها هستش، نرمال‌سازی زیاد می‌تونه کارایی خوندن داده‌ها را کاهش بده.افزایش تعداد جداول و پیوستن‌ها (Joins) 👈 به دلیل وجود جدول های زیاد، نیاز به پیوستن جداول بیشتره که این خودش میتونه کارایی کوئری‌ها را کاهش بده.امیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود تا قسمت بعدی ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Thu, 07 Nov 2024 13:26:20 +0330</pubDate>
            </item>
                    <item>
                <title>دیتابیس بدون ایندکس، مثل کتابخانه بدون فهرست! (قسمت سوم از مفاهیم دیتابیس)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-%D8%A8%D8%AF%D9%88%D9%86-%D8%A7%DB%8C%D9%86%D8%AF%DA%A9%D8%B3-%D9%85%D8%AB%D9%84-%DA%A9%D8%AA%D8%A7%D8%A8%D8%AE%D8%A7%D9%86%D9%87-%D8%A8%D8%AF%D9%88%D9%86-%D9%81%D9%87%D8%B1%D8%B3%D8%AA-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-%D8%A7%D8%B2-%D9%85%D9%81%D8%A7%D9%87%DB%8C%D9%85-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-suqx8jbjkzwt</link>
                <description>به قسمت سوم از سری مجموعه مفاهیم دیتابیس خوش اومدی، توی این قسمت میخواییم به جادوگرهای پنهان سرعت یعنی ایندکس ها در دیتابیس‌ها بپردازیم. دقت کنید که توی این سری مجموعه ما با انواع مفاهیم دیتابیس آشنا میشیم و کاری با کد زدن و نوع خاصی از دیتابیسا ها نداریمهمچنین قسمت قبل رو میتونید از لینک زیر 👇بخونید:وقتی جدول‌ها عاشق می‌شوند (قسمت دوم از مفاهیم دیتابیس)✅ ایندکس ها چی هستن ؟؟؟فرض کنیم داریم یه کتاب حجیم با هزاران صفحه رو میخونیم. بدون داشتن فهرست یا ایندکس، اگر بخواییم مطلب خاصی رو پیدا کنیم باید دونه دونه ورق بزنیم تا پیداش کنیم. خب طبیعتا این کار خیلی خسته کننده میشهحالا اگه اون کتابمون فهرست یا همون index داشته باشه خیلی راحت میبینیم فلان مطلب توی کدوم صفحه اس و مستقیم میریم سر وقتش و دیگه نیاز نیست کل کتابو بگردیدیتابیس هم دقیقاً همین رخ میده. وقتی شما ایندکس میسازی، یک ساختار داده‌ای ایجاد میشه که به پایگاه داده میگه هر داده کجا قرار گرفته. مثلاً اگه یک ایندکس روی ستون name در جدول Students داشته باشید و به دنبال دانشجویی به اسم &quot;علی&quot; باشید، دیتابیس به جای جستجو در همه رکوردها، مستقیماً به ردیف‌های مربوط به &quot;علی&quot; میره و نتیجه رو خیلی خیلی سریع‌تر به شما میده.پس وقتی روی یک یا چند ستون ایندکس انجام میدیم، دیتابیس لیستی از مقادیر مرتب شده رو از اون ستون مورد نظر به همراه اشاره گر هایی به رکورد های اصلی ذخیره میکنه و دیگه به جای اینکه روی جدول اصلی جست و جو کنه میره توی جدول ایندکس خیلی سریع داده مربوطه رو پیدا میکنه .انگاری که پس قضیه یه جدول ایندکس ساخته میشه و دیتابیس از طریق اون ایندکس گذاری رو انجام میده مثل عکس زیر✅ انواع ایندکس ها ؟؟؟به طور کلی سه دسته بندی برای ایندکس ها داریم:ایندکس اولیه (Primary Index) 👈 این نوع ایندکس به طور پیش‌فرض روی کلید اصلی (Primary Key) ستون‌ها ایجاد میشه و تضمین می‌کنن که هر مقدار در کلید اصلی یکتا (Unique) باشه و به صورت خودکار موقع تعریف کلید اصلی ساخته می‌شود. این ایندکس معمولاً برای جستجوی سریع استفاده میشه. وقتی Primary Key درست کنی خود دیتابیس این کارا رو برات میکنه.ایندکس خوشه‌بندی (Clustered Index) 👈 توی این نوع ایندکس، داده‌های جدول به ترتیب فیزیکی بر اساس این ایندکس مرتب میشن. این یعنی که تنها یک ایندکس خوشه‌بندی برای هر جدول میتونه وجود داشته باشه، چرا؟ چون داده‌های جدول تنها میتونن به یک شکل مرتب بشن. این نوع ایندکس‌ها دسترسی بسیار سریع به داده‌ها رو دارن.ایندکس غیرخوشه‌بندی (Non-Clustered Index) 👈 توی این نوع ایندکس، داده‌های جدول به ترتیب خاصی مرتب نمیشن، اما یک اشاره‌گر به محل ذخیره داده‌ها در خود جدول دارن. پس میتونیم برعکس ایندکس خوشه بندی، چندین ایندکس غیرخوشه‌بندی روی یک جدول ایجاد داشته باشیم.سوال: یعنی چی میگی داده ها به صورت فیزیکی مرتب میشن(فرق خوشه بندی و غیرخوشه بندی) ؟؟؟  یعنی اون داده مستقیما با ایندکس شدن روی دیسک میشینه و دیگه عین ایندکس Non-Clustered پس قضیه جدول درست نمیکنه توی Non-Clustered یه جدول برای ایندکس درست میشه و با اشاره گر هایی به اون جدول اصلی متصل میشه امیدوارم قابل فهم توضیح داده باشم✅ سایر ایندکس ها:یه سری ایندکس خاص دیگه داریم که خب هر کدوم به تنهایی یه مقاله جدا میطلبه ولی کوتاه هرکدوم رو توضیح میدم و اگه خواستین بیشتر راجبشون بدونید سرچشون کنیدایندکس Bitmap  👈 برای ستون‌هایی با تعداد مقادیر کم (کاراکترهای محدود) مناسبه، و معمولاً در انبارهای داده (Data Warehousing) استفاده میشه.ایندکس Hash  👈 از یک تابع هش برای نگاشت مقادیر به موقعیت‌های خاص استفاده میکنه؛ ایده‌آل برای جستجوهای تطبیق دقیق (Exact Match).ایندکس Filtered  👈 تنها زیرمجموعه‌ای از رکوردها را بر اساس یک شرط خاص ایندکس میکنه و برای بهبود سرعت کوئری‌ها روی ستون‌های پرتکرار مناسبه.ایندکس Covering  👈 شامل تمامی ستون‌های موردنیاز کوئری درون خود ایندکس، و دیگه نیازی به دسترسی به جدول اصلی نیست.ایندکس Function-Based  👈 ایندکسی که براساس نتیجه یک تابع یا عبارت اعمال شده بر روی یک یا چند ستون ایجاد میشه.ایندکس Full-Text  👈 برای جستجوی متن کامل طراحی شده و امکان جستجوی کارآمد در داده‌های متنی را فراهم میکنه.ایندکس Spatial  👈 برای ایندکس کردن داده‌های جغرافیایی کاربرد دارد، مثل داده‌های موقعیت‌یابی جغرافیایی.سه نوع ساختار داده مهم توی دیتابیس ها هستش که یه صورت خلاصه بررسیشون میکنیم:✅ ساختارداده B-tree:یک ساختمان داده قدرتمند که توی ایندکس ها ازش استفاده میشه، بریم یه خرده بررسیش کنیم:ساختاری سلسله‌مراتبی داره که شامل یک گره ریشه (Root Node)، گره‌های میانی (یا گره‌های ایندکس) و گره‌های برگ(leaf nodes) هست و همون طور که توی شکل زیر میبینید در هر گره‌ی B-Tree، یک آرایه مرتب(ordered) از کلیدها و اشاره‌گرها به گره‌های فرزند وجود دارد.حالا اصلا چرا B-tree ؟؟؟متعادل‌سازی خودکار(Self-Balancing) 👈 B-Tree همیشه ارتفاع خودشو در حالت متعادل نگه می‌دارد(چقد باهوشه)، حتی وقتی داده اضافه یا حذف میشه. این ویژگی باعث میشه عملیات درج، حذف، و جستجو با زمان‌بندی لگاریتمی(time complexity) خوبی انجام بشه.مرتب بودن(ordered) 👈 B-Tree داده‌ها را به صورت مرتب نگه میداره، بنابراین جستجوهای بازه‌ای مثل سفارشات فلان تاریخ x تا فلان تاریخ y یا مقاله های فلان x روز تا فلان y روز رو و مقایسه‌ها سریع‌تر انجام میده.سازگار با دیسک(Disk-Friendly) 👈 B-Tree طوری طراحی شده که با حافظه‌های مبتنی بر دیسک خوب کار میکنه. هر گره B-Tree معمولاً معادل یک بلاک دیسکه و با این کار، عملیات دسترسی به دیسک به حداقل می‌رسه.✅ ساختارداده Hash Table:جدول هش یک نوع ساختار داده‌ای هست که برای ایندکس‌های هش استفاده میشه و به کمک یک تابع هش هم کار میکنه.این جدول شامل مجموعه‌ای از باکت‌ها هستش. هر باکت شامل آدرس‌هایه که به سطرهای جدول داده اشاره دارن.باکت چیه ؟؟؟باکت (Bucket) در جدول هش به معنی یک فضای ذخیره‌سازیه که میتونه شامل یک یا چند مقدار باشه. در واقع، باکت‌ها مکان‌هایی هستن که داده‌ها در جدول هش به اون ها map یا همون اختصاص داده میشه و تابع هش مشخص میکنه که هر داده در کدام باکت قرار بگیرهایندکس‌های هش از تابع هش استفاده میکنن تا کلیدها را به باکت‌های مشخصی در جدول هش اختصاص بدن، که این کار  باعث میشه داده‌ها رو با سرعت بسیار بالا و در زمان ثابت پیدا کنیم(به همین خوشمزگی).حالا این نوع ایندکس کجا خوبه و کجا بده ؟  برای جستجوهای تطبیق دقیق (مثل جستجوی داده با یک مقدار خاص) بسیار سریع هستن، چون تابع هش مستقیماً محل دقیق داده را مشخص میکنه و میزنه تو خال. اما این ایندکس‌ها برای جستجوهای بازه‌ای (مثل پیدا کردن داده‌ها بین دو مقدار) یا مرتب‌سازی مناسب نیستن و نبیاد ازش استفاده کرد پس حواستون باشه ✅ ساختارداده Bitmaps :در این نوع ایندکس ها، برای هر سطر یک بیت (0 یا 1) اختصاص داده میشه. این بیت نشون میده که که آیا مقدار خاصی توی اون سطر وجود داره یا نه. به زبون  ساده‌تر بخوام بگم، بیت‌مپ یک آرایه باینری (از 0 و 1 تشکیل شده) که حضور یا عدم حضور یک مقدار خاص رو در هر سطر جدول نشون میده.برای ستون‌هایی که تعداد مقادیر ممکن کمی دارند (مثلاً &quot;true&quot; و &quot;false&quot;)  مناسب‌ هستن و به ویژه در جستجوهای پیچیده با شرایط متعدد کارایی خوبی دارند.و به عنوان نکته اخر عملیات‌هایی مثل AND، OR، و NOT روی بیت‌ها به راحتی و با سرعت بالا انجام میشه، پس  برای کوئری‌های تحلیلی که چندین ستون را شامل میشن، مناسب هستن.✅ کی و چه موقع استفاده کنیم ؟؟؟دقت کنید درسته indexing سرعت رو زیاد میکنه ولی حواستون باشه بدی هایی هم داره مثلا اگه توی دیتابیس زیادی عملیات insert و update دارید از ایندکس کمتر استفاده کنید چون علاوه بر دیتا اصلی اون جدول های ایندکس هم باید بروز بشن و این ممکن دیتابیس رو کند کنهالبته خب یکسری جاها باید برای بدست اوردن یه چیزی، چیز دیگه ای رو از دست داد و بسته به پروژه و نوع کار مشخص میشه چه موقع از ایندکس استفاده کنیم یادتون نره که توی صنعت نرم افزار همه چیز trade off هست و خوب و بد مطلق نداریمامیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود تا قسمت بعدی ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Thu, 31 Oct 2024 21:05:59 +0330</pubDate>
            </item>
                    <item>
                <title>وقتی جدول‌ها عاشق می‌شوند (قسمت دوم از مفاهیم دیتابیس)</title>
                <link>https://virgool.io/@MohammadBohluli/%D9%88%D9%82%D8%AA%DB%8C-%D8%AC%D8%AF%D9%88%D9%84-%D9%87%D8%A7-%D8%B9%D8%A7%D8%B4%D9%82-%D9%85%DB%8C-%D8%B4%D9%88%D9%86%D8%AF-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-%D8%A7%D8%B2-%D9%85%D9%81%D8%A7%D9%87%DB%8C%D9%85-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-oefzoffyztu7</link>
                <description> خب خب رسیدیم به قسمت دوم از سری مجموعه مفاهیم دیتابیس، توی این قسمت میخواییم به مفهوم کلید ها و عشق و رابطه میون جدول ها رو مورد بررسی قرار بدیم. دقت کنید که توی این سری مجموعه ما با انواع مفاهیم دیتابیس آشنا میشیم و کاری با کد زدن و نوع خاصی از دیتابیسا ها نداریمهمچنین قسمت قبل رو میتونید از لینک زیر 👇بخونید: نبرد بین نظم و انعطاف (قسمت اول از مفاهیم دیتابیس)✅ اول ببینیم کلید (keys) توی دیتابیس چیه و اصلا چرا بهش نیاز داریم ؟؟؟توی دیتابیس‌ها، کلیدها (Keys) نقش خیلی مهمی در مدیریت داده‌ها و ایجاد ارتباط بین جداول ها رو دارند و هر نوع کلید هدف خاصی دارد که به سازماندهی داده‌ها و جلوگیری از تناقض کمک می‌کندبه زبون ساده تر بخوام بگم، وقتی شما یه جدول میسازید و یکسری داده توش دارید خب هر داده باید یه چیز یونیک داشته باشه که بشه اون رو از بقیه داده ها تشخیص داد دیگه؟ به اون چیز یونیک میگن کلید. دقیقا عین کدملی هر ایرانی که یک چیز unique یا همون یکتا برای هر شخص هستنوع کلید بسته به پروژه میتونه هر چیزی باشه مثلا ایمیل، UUID یا شماره تلفن یا هرچیزی باشه✅ انواع کلید ها رو بشناس :(جلوتر مثال هاشون رو میزنم)کلید اصلی (primary key) 👈 کلید اصلی یک ستون  توی یک جدول، که به‌طور منحصربه‌فرد هر ردیف(رکورد) رو شناسایی می‌کنه و هر جدول فقط می‌تواند یک کلید اصلی داشته باشد. دقت کن که این کلید باید یونیک(Unique) باشد و مقدار null را نپذیرد یعنی تو نمیتونی دوتا موجودیت مثل کاربر رو پیدا کنی  که هردوتاشون کدملی یکسانی داشته باشن یا اصلا کد ملی نداشته باشن و null  باشنکلید خارجی (foreign key) 👈 کلید خارجی یا کلید ارجاعی، برای ایجاد ارتباط بین دو جدول استفاده میشه. این کلید به ستون یا کلید اصلی در جدول دیگری اشاره می‌کند و به یکپارچگی داده‌ها کمک می‌کند(بعدن مفهوم یکپارچگی رو توی مبحث ACID توضیح میدم فعلا زیرپوستی بگذر ازش) دقت کن این کلید برعکس کلید اصلی میتونه مقدار null بگیرهکلید ترکیبی (Composite Key) 👈 کلید ترکیبی ، ترکیبی از دو یا تعداد بیشتری ستون است که به طور یکتایی سطرها را در جدول  را شناسایی می‌کند. دقت کنید که ترکیب این ستون ها(نه فقط یک ستون) هستش که  یکتا بودن رو تضمین می‌کنه، اگرچه، یکتا بودن به صورت مستقل تضمین نمیشه. پس، دو یا تعداد بیشتری از ستون‌ها ترکیب میشن تا رکوردها را به صورت یکتایی بتونیم شناسایی کنیم. مثلا فرض کن نام و نام خانوادگی و اسم پدر هر کدوم جدا هستن اما ترکیب این سه تا یک کلید ترکیبی میشه که بتونیم یک شخص رو بشناسیم ولی هرکدوم به تنهایی معلوم نمیکنه که اون شخص کیهتقریبا مهم تریناش این سه تا بودن که گفتم وگرنه کلید های خیلی زیاد تری هستن که میشه تا صبح راجبشون بحث کرد و خب مقاله خیلی طولانی میشه. میتونید با سرچ ساده پیداشون کنید(توی عکس زیرم هستن)خب نوبتی هم که باشه نوبت ارتباط میون جدول ها و عشق بازی❤️ اونها هستش✅ اصلا این روابط چی هست ؟؟؟توی دیتابیس‌ها، روابط (Relationships) نقش مهمی توی ساختاردهی داده‌ها و برقراری ارتباط بین جداول دارن. این روابط به ما کمک میکنن که داده‌های مرتبط را به‌طور مؤثرتری مدیریت کنیم. چهار نوع اصلی رابطه وجود داره که باهم بررسیشون میکنیم✅ رابطه یک به یک(One To One) یا 1:1 در رابطه یک به یک، هر رکورد از یک جدول با دقیقاً یک رکورد از جدول دیگر مرتبط است. از این رابطه زمانی استفاده میکنیم که دو مجموعه داده کاملاً مرتبط باشن ولی دلایل خاصی برای جدا کردن آن‌ها به دو جدول وجود داشته باشد، مثل مسائل امنیتی یا بهینه‌سازی.فرض کن یه جدول user داریم که کلی اطلاعات توشه خب برای اینکه هم دیزاین بهتری داشته باشیم و هم بهینه تر بشه میتونیم اطلاعاتی که اهمیتشون کمتره رو توی جدولی به اسم profile بزاریم و این دوتارو به صورت یک به یک به هم متصل کنیم یعنی به اعضای هر یک دونه یوزر فقط و فقط یک دونه پروفایل وجود داشته باشه و این دوتا از طریق کلید اصلی به هم متصل میشنتوی عکس زیر جدول یوزر و پروفایل از طریق کلید اصلی userId با هم ارتباط یک به یک دارن✅ رابطه یک به چند(One To Many) یا 1:n در رابطه یک به چند، هر رکورد در جدول اول میتونه با صفر یا یک یا چند رکورد از جدول دوم مرتبط باشد، ولی هر رکورد در جدول دوم فقط با یک رکورد از جدول اول مرتبط است. این نوع رابطه یکی از رایج‌ترین روابط در دیتابیس‌هاس.فرض کنید یه جدول داریم به اسم کاربر و یک جدول دیگه به اسم articles حالا بیایین تحلیلش کنیم، همیشه برای تحلیل از این جمله استفاده کنیدa user has many article and a article has one userحالا همه چی مشخص شد، هر کاربر میتونه چندین مقاله داشته باشه اما هر مقاله فقط و فقط مربوط به یک یوزر هست پس رابطمون میشه یک به چند. اینجاست که کلید خارجی به کار میاد و باید ازش استفاده کنیم. در واقع هر مقاله از طریق یک userId به اون کاربر مورد نظر متصل شده پس userId مورد نظر توی جدول article میشه کلید خارجی ما✅ رابطه چند به چند(Many To Many) یا m:n در رابطه چند به چند، هر رکورد از یک جدول متونه با چند رکورد از جدول دیگر مرتبط باشد و بالعکس. برای پیاده‌سازی این نوع رابطه، معمولاً یک جدول میانی (junction table) استفاده میشه که ارتباط بین دو جدول اصلی را مدیریت میکنه.مثلا رابطه جدول articles با جدول tags یک رابطه چند به چند هست.چرا؟بیایین تحلیلش کنیم: هر مقاله میتونه دارای چندین تگ باشه و هر تگ هم میتونه متعلق به چندین مقاله باشه پس رابطه ما میشه چند به چندنکته این رابطه اینه که باید یه جدول دیگه هم بسازیم تا جدول مقاله با تگ هارو به هم متصل کنهالبته این نکته رو هم بگم اگه از ORM ها استفاده میکنید براتون این قضیه ساخت جدول میانی many to many رو حل کردن و نیاز نیست شما کاری کنید✅ تکلیف حذف کردن ها چی میشه پس :خب حالا فرض کنید یه کاربر 100 تا مقاله نوشته و یهو تصمیم میگیره اکانتشو از سایت پاک کنه پس تکلیف اون صد تا مقاله چی میشه ؟اینجاست که دیتابیس ها چیزی به اسم ON DELETE دارن که دقیقا برای همین کار ساخته شده . یعنی در تنظیمات روابط دیتابیس، گزینه‌های ON DELETE مشخص میکنه که هنگام حذف رکورد مرجع (parent)  که اینجا منظور user هست، چه اتفاقی برای رکوردهای مرتبط (child) یعنی articles بیوفته.✅ انواع ON DELETE :مقدار ON DELETE CASCADE :با حذف رکورد مرجع(user)، رکوردهای مرتبط در جدول دیگر(articles) نیز به‌طور خودکار حذف می‌شوند.مثال: اگر یک کاربر حذف بشه، تمام مقالات مرتبط با اون هم حذف خواهند شد.مقدار ON DELETE SET NULL :با حذف رکورد مرجع(user)، مقدار ستون کلید خارجی در رکوردهای مرتبط(articles) به null تنظیم می‌شود.مثال: اگر یک کاربر حذف شود، مقاله های مرتبط به null تغییر می‌کنن.مقدار ON DELETE RESTRICT :از حذف رکورد مرجع(user) تا زمانی که رکوردهای مرتبط(articles) وجود دارند جلوگیری می‌کند مثال: اگر یک کاربر مقالاتی داشته باشه، حذف کاربر مجاز نیست تا زمانی که مقالات او حذف شوند.مقدار ON DELETE NO ACTION :مثلRESTRICT عمل می‌کند اما بدون تأثیر مستقیم بر تراکنش‌ها؛ حذف بدون خطا انجام می‌شود اما تغییرات وابسته نادیده گرفته می‌شود.مقدار ON DELETE SET DEFAULT :با حذف رکورد مرجع، مقدار ستون کلید خارجی در رکوردهای مرتبط به مقدار پیش‌فرضی تنظیم می‌شود (در صورتی که پیش‌فرضی تعریف شده باشد).امیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود تا قسمت بعدی ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Thu, 24 Oct 2024 20:36:46 +0330</pubDate>
            </item>
                    <item>
                <title>نبرد بین نظم و انعطاف (قسمت اول از مفاهیم دیتابیس)</title>
                <link>https://virgool.io/@MohammadBohluli/%D9%86%D8%A8%D8%B1%D8%AF-%D8%A8%DB%8C%D9%86-%D9%86%D8%B8%D9%85-%D9%88-%D8%A7%D9%86%D8%B9%D8%B7%D8%A7%D9%81-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-%D8%A7%D8%B2-%D9%85%D9%81%D8%A7%D9%87%DB%8C%D9%85-%D8%AF%DB%8C%D8%AA%D8%A7%D8%A8%DB%8C%D8%B3-f2lpllbaofac</link>
                <description>تصمیم دارم یک سری مجموعه از مفاهیم دیتابیس بسازم اما قرار نیست توش کد بزنیم و بگیم SELECT چیه و چه موقع از WHERE استفاده کنیم ، بلکه قراره بریم تو قلب مفاهیم و اون مهم هاشو یاد بگیریم تا طراحی بهتری داشته باشیمتوی اولین قسمت از سری مجموعه مفاهیم دیتابیس قراره خون و خون ریزی 🔪راه بیوفته بین دو نوع دیتابیس یعنی SQL و NoSQLمیخواییم یاد بگیریم که اصلا کی به وجود اومدن؟ چرا به وجود اومدن؟ چه موقع از کدوم استفاده کنیم و چه موقع استفاده نکنیم؟ مزیت و معایبشون چیه؟ به درد چه پروژه هایی میخوره ؟ اول بریم سراغ اونی که سنش بیشتره یعنی SQL ها✅ تاریخچه هادیتابیس های SQL یا Structured Query Language یا ساختاریافتهاین نوع دیتابیس ها راه حلی برای ذخیره‌سازی و مدیریت داده‌های ساختارمند به وجود اومدن تقریبا در دهه ۱۹۷۰، شرکت ابرقدرت و ابر شوکت😁 IBM با تحقیقاتی که انجام داده بود یک مدل رابطه‌ای برای دیتابیس‌ها معرفی کرد.هدف از این مدل چی بود ؟؟؟ میخواست که یک روش ساختاریافته رو برای ذخیره داده درست کنه پس چی شد ؟ SQL به عنوان زبان استاندارد برای مدیریت و پرس‌وجوی دیتابیس‌های رابطه‌ای به دنیا اومد👼.این دیتابیس ها در سیستم‌های بانکی، تجاری، و مالی که داده‌ها بسیار حساس و پیچیده بودند مورد استفاده قرار گرفتن و به سرعت به عنوان استاندارد صنعتی پذیرفته شدن و خب پشت بندش دیتابیس های Oracle، MySQL، و PostgreSQL بر پایه همین SQL ساخته شدند.دیتابیس های NoSQL یا غیرساختار یافتهرفته رفته اینترنت، شبکه های اجتماعی، موتور های جست و جو خلاصه همه چی اوج گرفت و حجم داده ا به سقف میزد و در دهه ۲۰۰۰، دیتابیس رابطه‌ای با چالش‌هایی مواجه شدند مثلا برای داده های منعطف تر کارایی لازم رو نداشتن، مثلا سرعتشون کمتر بود یا برای مقیاس پذیری عمودی معمولا ساخته شده بودنپس گوگل و آمازون دست به کار شدن مدل Not Only SQL رو اوکی کردن و پشت بندشم دیتابیس های مونگو و ردیس و امثال اینا ساخته شدالان ممکنه یک سری از دوستان گل بگن عه عه ببین سرعت SQL کمه پس دیگه هممممه پروژه ها رو با mongo بیاریم بالا😒، ببینید ما داریم توی اسکیل گوگل و آمازون حرف میزنیم(یعنی میلیاااردی) با این حال اونا بازم دارن از sql ها استفاده میکنن و هرکدوم از این دو نوع به پروژه بستگی داره و هیچ کدوم بر دیگری برتری ندارن✅ نوع ساختار داده هادیتابیس های SQL یا Structured Query Language یا ساختاریافتهاین نوع دیتابیس ها از یک مدل جدولی یا همون Table استفاده می‌کنند. داده‌های ما در جداول با ردیف‌ها و ستون‌ها ذخیره میشن و هر سطر، به عنوان یک رکورد شناخته میشه. این ساختار باعث میشه که SQL مناسب برای داده‌های ساختارمند و دارای ارتباطات پیچیده باشد. عکس زیر گویای همه چیزهپس وقتی دیدی خیلی ریلیشن یا ارتباط بین داده هات هست بیا سمت این نوع دیتابیسا(مقاله های آینده بیشتر توضیح میدم)دیتابیس های NoSQL یا غیرساختار یافتهاین دیتابیس‌ها از مدل‌های مختلفی برای ذخیره داده‌ها استفاده می‌کنند، مثلا دیتابیس های داکیومنتی مثل مونگو  از ساختار(document-oriented) استفاده میکنن، دیتابیسی مثل ردیس از ساختار کلید-مقدار (key-value)، و دیتابیس مثل neo4j، گراف استفاده میکنه. داده‌ها در NoSQL بدون نیاز به ساختار جدولی و به صورت غیرساختارمند ذخیره میشن که باعث انعطاف‌پذیری بیشتر می‌شود. مثلا توی مونگو ماشالله به هیچ دیتایی نه نمیگه هرچی بدی بهش برات ذخیره میکنه انقدی که بچه خوب و منعطفیه✅ مقیاس پذیریدیتابیس های SQL یا Structured Query Language یا ساختاریافتهاین نوع دیتابیس ها معمولاً برای مقیاس‌پذیری عمودی(vertical) طراحی شده‌اند. حالا این عمودی یعنی چی ؟ ببینید دو نوع مقیاس پذیری هست که توی دیتابیسا استفاده میشه یکی عمودی یکی افقی حالا وقتی میگیم برای مقیاس پذیری عمودی بهتر عمل میکنن یعنی اینکه سخت‌افزارمون رو ارتقا بدیم مثلا  برای افزایش توانایی سرور، رم یا سی پی یو یا هارد یا هرچیزی که کمک کنه اضافه کنیمدیتابیس های NoSQL یا غیرساختار یافتهاین نوع دیتابیس ها معمولاً برای مقیاس‌پذیری افقی (horizontal) طراحی شده‌اند. توی این نوع مقیاس پذیری به جای اینکه سرور رو ارتقا بدیم میاییم سرور های دیگه رو اضافه میکنیممقیاس پذیری افقی مثل اضافه کردن چندتا ماشین هست و مقیاس پذیری عمودی مثل قدرتمند تر کردن اون ماشین هست✅ چه موقع از کدوم استفاده کنیم ؟فرض کنید یه اپلیکیشن که برای دانشگاه هستش رو میخوایین پیاده سازی کنید، خب طبیعتا دیتابیسی که میخواید طراحی کندی ارتباط میون جدول هاتون زیاد میشه مثل ارتباط بین دانشجو، استاد،درس، گروه ، واحد و ... و خب کار عقلانی اینه از دیتابیس های SQL محور استفاده کنیمحالا فرض کنید یه فروشگاه داریم که هر نوع کالایی توش به فروش میره مثل موبایل، تلوزیون، یخچال و ... خب هرکدوم از اینا فیلد های متفاوتی دارن مثلا مشخصات یخچال قطع فرق میکنه با مشخصات یک تلوزیون و خب ممکنه خیلی هم ارتباطی بینشون نباشه پس کار بهتر اینه از مونگو که NoSql بیس هست استفاده کنیمدرکل همه چی وابسته به پروژه شما و اون چیزی که میخواید هستش ولی به شخصه من خودم سرعت آخرین معیار برای انتخابم هست😏ببینید اینکه میگم NoSql برای داده هایی با ریلیشن زیاد خیلی مناسب نیست منظورم این نیست کلا نمیشه ریلیشن زد ها !!! توی NoSql هم ریلیشن داریم ولی یه خرده با SQL متفاوت هست مثلا توی NoSQL رفرنس و امبد داریم که قسمت بشه تو مقاله های آینده توضیح میدم✅ نتیجه گیری :اگه داده هات انعطاف زیادی مطلبه، مقیاس پذیری افقی معمولا به کارت میاد، حجم داده هات بشدت بالاس، داده هات غیر ساختارمند یا نیمه ساختارمند هستن و در آخرم نیاز به سرعت زیاد تری داری(جای بحث داره) بیا سمت NoSql هااما اگه داده هات ساختار سفت و سخت دارن و نظم بیشتر برات اهمیت داره، ریلیشن زیاد داری، تراکنش های حساس داری مثل یک سیستم بانکداری حساس که یکئارچه هستن بیا از SQL ها استفاده کنبازم میگم همه چیز ترید آف هستش و صفر و یک مطلق نیست و بسته به پروژه متفاوت هستش و این چیزایی که گفتیم صرفا یه چیز عمومی هستشامیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود تا قسمت بعدی ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Thu, 17 Oct 2024 18:08:11 +0330</pubDate>
            </item>
                    <item>
                <title>میدلور چیه؟ و Best Practices هاش کدومه ؟</title>
                <link>https://virgool.io/@MohammadBohluli/%D9%85%DB%8C%D8%AF%D9%84%D9%88%D8%B1-%DA%86%DB%8C%D9%87-%D9%88-best-practices-%D9%87%D8%A7%D8%B4-%DA%A9%D8%AF%D9%88%D9%85%D9%87-bqk7lcymvdin</link>
                <description>توی این مقاله میخوایم  با middleware ها توی  express.js و کلا دنیای Node.js آشنا بشیم و خب پیشفرض من اینه که حداقل با یکی از فریمورک های بک اندی جاواسکریپتی آشنایی دارید یا کار کردین اما در کل فارغ از هر نوع زبان برنامه نویسی یا فریمورکی  مفهوم middleware توی همه شون مشترک هست و صرفا اینجا مثال هامون با فریمورک express.js هستببینید وقتی ما یک Request به سمت اپلیکیشن یا وب سایت مورد نظر میفرستیم یکسری پردازش ها روش انجام میشه و بعدش یک Response به ما بر میگردهحالا این وسط مسطا یه تابعی هست که به اون Request و Response دسترسی داره و میتونه یکسری کارها که ما براش تعیین میکنیم روی اونها انجام بده، به اون تابع میگیم میان افزار یا همون middleware این میشه یک تعریف خیلی ساده (عکس زیر رو ببین)middlewareهمون طور که توی عکس زیر میبینید سینتکس middleware تو اکسپرس این شکلی هست:هر تابع middleware یک request و response  و next میگیره، request و response که معلومه چی هستن و خب میمونه next، کار این next اینه درخواست رو به middleware بعدی بفرسته اما دقت کن اگه یادت بره next رو صدا بزنی اپلیکیشنت میره توی عالم هپروت و هنگ میکنهوقتی هم که از میدلور میخوایم استفاده کنیم اون رو به ()app.use پاس میدیم یا اینکه مثل عکس بالا به اون متد مورد نظر پاسش میدیماز middleware ها معمولا برای موارد زیر استفاده میکنن:وقتی که میخوایم logger درست کنیم یا یک چیزی رو log بندازیموقتی که میخوایم احرازهویت یا authentication و athurization ایی انجام بدیموقتی که میخوایم مدیریت خطا یا error handling انجام بدیم (که توی این مورد باید error رو به صورت متغییر چهارم به میدلورت پاس بدی)وقتی که میخوایم یک داده ای رو pars کنیموقتی که ......(خیلی کار های دیگه)توی مثال ساده زیر یک میدلور نوشتیم که هر درخواستی میاد سمت سرورمون show request رو لاگ بندازهconst express = require(&#039;express&#039;);
const app = express();

app.use((req, res, next) =&gt; {
    console.log(&amp;quotshow request&amp;quot);
    next();
});

app.get(&#039;/&#039;, (req, res) =&gt; {
    res.send(&amp;quotHello world&amp;quot);
});

app.listen(3000, () =&gt; {
    console.log(&amp;quot server is running &amp;quot);
});به نظرم مفهوم اصلی رسونده شده و بقیه شو خیلی خیلی کامل تر میتونید از مستندات سایت express.js یا فریمورک مد نظرتون پیگیری کنید و از اینجا به بعد مختص جاواسکریپتی ها و express.js هست ولی بازم به درد بقیه فریمورک ها هم میخورهبریم یه خرده Best Practices راجع به middleware ها یاد بگیریم:میدلور تونو همیشه کوچیک و متمرکز نگهداریدیعنی تا جایی که امکان دار کد هارو توش ساده نگهدارید و فقط و فقط هر میدلور یک کار به خصوص رو انجام بده، یعنی اینطوری نباشه یه میدلور نوشتی هم ارور رو لاگ میندازه هم احرازهویت رو انجام میده، اینطوری دیباگ کردن و تست نویسی برات خیلی سخت میشه پس یادت نره هر کدی که مینویسی بعدن باید ازش پشتیبانی و نگهداری کنیا !!!!همیشه خدا یادتون باشه next رو صدا بزنیدهمون طور که قبلنم گفتم اگه یادت بره next رو صدا بزنی باعث میشه اپلیکیشنت دچار اختلال بشه و به درستی درخواست هارو به میدلور های بعدی انتقال نده پس با صدا زدن next میدلور هات انعطاف زیادی پیدا میکنن و زنجیره میلدوریت به دستی کار میکنه و میتونی به راحتی کی میدلور رو حذف یا اضافه کنی بدون اینکه اختلالی توی اپلیکیشن ایجاد بشههمیشه خطا هارو توی میدلورت مدیریت کنبا استفاده از یک try/catch ساده میتونی هر میدلوری که نوشتی اگه خطایی توش رخ بده اون رو به صورت متمرکز توی یک جا مدیریت کنی و اینم یادت باشه همیشه یک میدلور برای مدیریت خطاهات داشته باش که مسئول همین کار باشه و تمام مدیولر هات خطا رو به اون پاس بدنمراقب ترتیب میدلور هات باشترتیب یا همون ordering توی میدلور مهمهف چون این میدلور هات به ترتیب اجرا میشن دیگه. یعنی اینطوری نباشه که تو میدلور error handling رو بیایی اول بزاری بعد احرازهویتت رو اخر بزاری چون اصلا معنی نمیدهاسم با معنی انتخاب کننه فقط برای میدلور هات بلکه برای توابع و کلا توی کدنویسی از اسامی با معنی استفاده کن مثلا کد زیر قراره یه چیزی رو لاگ بندازه پس منطقیه اسمش رو بزاریم logger و هدف اون قطعه کد رو میرسونه و هکس بیاد اسمش رو ببینه درجا میفهمه این میدلور قراره چکار کنهاز ()app.use توی route handlers استفاده نکنیداین کار باعث میشه پیچیدگی کدتون زیاد بشه و اصل separation of concerns هم زیر پا بزارید، پس هیچوقت از ()app.use توی هندلر هاتون استفاده نکنید از return توی مدیلورت استفاده کناینکار از پردازش های غیر ضروری جلوگیری میکنه پس وقتی کار میدلورت تموم میشه مقدار یا عبارت یا هرچیزی که مدنظرت هست رو return کن تا زنجیره میدلوریت ادامه پیدا کنه و از اجرای کد های غیر ضروری جلوگیری بشهامیدوارم مورد استفاده اتون قرار گرفته باشهاگه دوست داشتید توی کانال تلگرامیمون هم عضو بشید LearnByLearn@بدروووود ❤️منابع:https://expressjs.com/en/guide/using-middleware.htmlhttps://expressjs.com/en/guide/writing-middleware.htmlhttps://medium.com/deno-the-complete-reference/node-js-8-best-practices-for-express-middlewares-bb5825ec0844</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Tue, 03 Sep 2024 21:24:48 +0330</pubDate>
            </item>
                    <item>
                <title>قسمت ششم (all about inheritance in js)</title>
                <link>https://virgool.io/@MohammadBohluli/%D9%82%D8%B3%D9%85%D8%AA-%D8%B4%D8%B4%D9%85-all-about-inheritance-in-js-uuahetmvzcpe</link>
                <description>توی این قسمت هر آنچه از ارث بری رو  که بلد بودم، یکجا جمع کردم که درکش راحت تر باشهتوی جلسات قبلی(لینکشون توی پروفایلم هستن) راجع به prototype inheritance صحبت کردیمو سه تکنیک ساخت برنامه شی گرا با constructor function و  ES6 Class و Object.create رو یاد گرفتیم و همشون این اجازه رو به آبجکت میدن که متد ها و پراپرتی هارو توسط  prototype رو به ارث ببرهاما چیزی که توی این مقاله میخواییم بگیم، ارث بری بین کلاس هاست نه ارث بری prototype و حواستون باشه این دوتا یعنی ارث بری بین دوتا کلاس و ارث بری prototype رو باهم اشتباه نگیرید.توی ارث بری کلاس ها، به کلاس والد parent یا class میگن و به کلاس فرزند child یا subclass میگناول بریم ارث بری رو توی constructor function بررسی کنیم:مثال زیر رو دقت کنید، دوتا constructor داریم یکی Person که میشه کلاس والد و یکی Student که میشه کلاس child ما و هرکدوم از این ها هم متد و پراپرتی خودشونو دارن(خط به خط  کد زیر رو توضیح خواهم داد فقط زیر چشمی نگاهتون بهش باشه 😏)constructor function exampleتوی کلاس Student ما نیاز به firstName و birthday داریم اما اگه بیاییم مثل کلاس والد باز تعریفشون کنیم اصل DRY رو زیر پا میزاریم و کد تکراری میشه پس از متد call برای به ارث بردنشون از کلاس والد استفاده میکنیمخب تا اینجای کار دوتا کلاس، constructor اشون باهم مچ شدن ولی method هاشون چی ؟ چطوری کلاس فرزند متد های کلاس والد رو به ارث ببره و بتونه بهشون دسترسی داشته باشه ؟فقط کافیه prototype هاشون رو با خط شماره 17 توی مثال به هم وصل کنیم با این کار کلاس فرزند هر آنچه که کلاس والد داره رو به ارث میبرهحالا یه سوال ممکنه پیش بیاد، چرا از Object.create استفاده کردیم؟ خب میشه توسط خط 19 پروتوتایپ والد رو بریزیم توی فرزند دیگه چکاریه آخه از Object.create استفاده کنیم 🤔یکم عمیق ترمون نشه😉 ؟؟؟ (دیاگرام زیر رو ببینید) اگه به جای Object.create از خط 19 استفاده کنیم، داریم به جاواسکریپت میگیم که بیا پروتوتایپ والد(Person) رو بزار توی پروتوتایپ فرزند(Student) پس عملا این وسط داریم Student.prototype رو حذف میکنیم و prototype chain (آموزش prototype chain) ما از بین میره،  فقط کافیه یه بار خط 19 رو بزارید توی کد هاتون یه بارم با Object.create امتحان کنید و از mike لاگ بگیرید تا بهتر درکش کنید چه اتفاقی میوفته اگه از خط 19 استفاده کنیم پس کلا فراموشش کن خط 19 رو خب حالا وقتی یه متد از متد های Person رو روی mike که از Student ساخته شده صدا کنیم، جاواسکریپت چطور این متد رو پیدا میکنه ؟( بازم دیاگرام زیر رو هنگام توضیحات ببینید)وقتی mike.calcAge() رو صدا میزنیم، جاواسکریپت اول از همه میره _ _ proto_ _ آبجکت mike رو میگرده اگه پیدا کرد که هیچی اگه پیدا نکرد میره سمت پروتوتایپ Student اگه بازم پیدا نکرد میره پروتوتایپه Person رو میگرده و اگرم پیدا نشد هیچی null برمیگرده.این است قدرت prototype chain 😎نکته : فقط یه مشکل کوچولویی پیش میاد این وسط اینه که  وقتی خط زیر رو لاگ بگیریدStudent.prototype.constructorمیاد constructor عه Person رو نشون میده پس با کد زیر این مشکل رو حل میکنیمStudent.prototype.constructor = Studentحالا دیگه constructor عه Student رو نشون میدهنکته: اگه بخواییم یک متد از Person رو توی کلاس Student به اصطلاح override کنیم یعنی باز نویسیش کنیم باید دقیقا اسم همون متد رو بنویسیم و بعدشم لاجیک مربوطه رو پیاده سازی کنیم و چون فهمیدید javascript چطور یه متد رو پیدا میکنه پس دیگه میبینه خود Student اون متد رو داره پس دیگه سراغ والد نمیرهبریم ارث بری توی ES6 Class رو بررسی کنیم:همون طور که توی قسمت های قبلی مقاله های شی گرایی گفتم، جاواسکریپت چیزی به اسم class نداره و این class که توی ES6 اضافه شده فقط یه پوسته اس و پس قضیه توسط constructor function ها هندل میشه بنابراین، ارث بری توی ES6 Class دقیقا همین اتفاقات بالا رخ میده فقط از نظر سینتکسی فرق میکنهمثال زیر رو ببینید و مقایسه اش کنید با ورژن constructor function اش که بالاتر مثالش هستهمه چیز کاملا شفافه فقط چندتا نکته راجع به کد بالا بگم:توی ES6 Class برای ارث بری بین کلاس والد و فرزند به جای خط زیر از کلمه کلیدی extends استفاده میکنیمPersonProto.init.call(this, firstName, birthday);تابع constructor هم که معلومه چیکار میکنه و برای اینکه از مقادیر constructor تابع والد بخواییم استفاده کنیم اومدیم به جای متد call از کلمه کلیدی super استفاده کردیم و کلمه کلیدی Super هم اسمش با خودشه میاد از superclass یعنی کلاس والد مقادیر رو میگیرهو اما آخرین نوع ارث بری هم مربوط میشه Object.create اگه نمیدونید چیه و چطور کار میکنه این مقاله رو بخون، اگرم میدونی چیه که خب مثال زیر رو ببین تا توضیح بدم ارث بری چطوری داخلش هندل میشهخب توی خط اول اومدیم یه پروتو برای Person ساختیم به اسم PersonProto و توسط Object.create ازش یک آبجکت ساختیم و ریختیمش توی steven حالا استیون یک شی هست که proto اش، PersonProto هست(تابع init حکم constructor رو بازی میکنه ولی اصلا خاصیت یک constructor رو نداره تو مقاله قبل گفتمش)حالا میخواییم یه کلاس فرزند داشته باشیم به اسم Student که تمام ویژگی های کلاس والدش یعنی Person رو داشته باشهخب کاری نداره که توی خط 14 باز از همون پروتوعه Person استفاده کردیم و به همین راحتی کل ویژگی هارو به ارث میبره و خب مثل مثال های قبل توی خط 16 اومدیم init رو override کردیم و توی خط 21 هم کلا یه متد جدید به Student اضاف کردیمحالا jay توی خط 25 یک شی هست که از proto اش StudentProto هست و به تمام متد های PersonProto دسترسی داره (به خاطر خط 14)دیاگرام زیر هم به صورت شهودی داره میگه که ارث بری توی Object.create چطور کار میکنه این شد کل ارث بری توی جاواسکریپت، چیزی نمونده بود که نگم و تا جایی که تونستم چیزایی که یاد گرفتم رو یک جا جمع کردم که مرجع خوبی بشهامیدوارم بدردت خورده باشه❤️کانال تلگرامم 👈 LeanByLearn@</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 02 Aug 2024 23:34:10 +0330</pubDate>
            </item>
                    <item>
                <title>شی گرایی قسمت پنجم (Object.create)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85-objectcreate-l6btjba88azk</link>
                <description>رسیدیم به نوع سوم ساخت شی یعنی ()Object.createاگه تا الان مقاله های قبل رو نخونید از این لینک شروع کنید به خوندنخب بریم سر اصل مطلب، اگه دقیت کرده باشید توی دو روش قبلی ما به چیزایی مثل تابع constructor و کلمه کلیدی یا همون اپراتور new نیاز داشتیم تا یه شی بسازیم یا مثلا یک متد رو دستی به پروتوتایپ اضافه کنیمخبر خوب اینکه دیگه با Object.create نیازی به اینا نداری :) برو حالشه ببرپس چطور باید بسازیم ؟مثال زیر رو ببیناول میاییم یه آبجکت به عنوان پروتوتایپ میسازیم و هر متد یا پراپرتی که نیازه داریم رو توش تعریف میکنیم مثلا اینجا ما calcAge رو نوشتیمتوی مرحله بعد فقط کافیه هر آبجکتی که دوست داشتیم بسازیم و از این پروتوتایپ استفاده کنه رو به Object.create پاس میدیم، تموم شد رفت به همین راحتی دیگه نه با تابع constructor نه  new نه prototype هیچی درگیری نشدیم و خیلی تمیز شددر واقع الان PersonProto نقش همون پروتوتایپ مارو بازی میکنه یه کنسول بگیری از آبجکت ali میبنیی که متد calcAge توی پروتوتایپش هست بدون اینکه اینطوری بنویسیمش Person.prototype.calcAgeاما چی شد که اینطوری شد ؟؟؟(دیاگرام زیر رو ببین تا برات توضیحش بدم)توی دو مورد قبلی (ES6 و constructor function) ما وقتی از اپراتور new استفاده میکردیم میومد اتوماتیک     _ _proto _ _  رو میساخت و اضافش میکرد(سمت چپ نمودار)اما توی ()Object.create ما اومدیم دستی پروتوتایپ یک ابجکت رو دستی اضافه کردیماینجا ما به صورت دستی PersonProto  رو از طریق Object.create وصل کردیم به __Person.__proto  و ارث بری پروتوتایپ و prototype chain دقیقا مثل همون دوتای قبلی هست و فرق مهمش اینه که اینجا دیگه چیزی به اسم تابع سازنده نداریم و همچنین  prototype property هم نداریمپس همون طور که بالاتر گفتم وقتی از Object.create استفاده میکنی دیگه نیاز نیست متد تو به Person.prototype.mymethod اضافه کنی بلکه کافیه به همون PersonProto اضاف کنی خودش اتوماتیک همه چیو برات ردیف میکنه (بعد هی بگید جی اس بده :) )اگه از __ali.__proto  یه دونه لاگ بگیری میبینی که متد calcAge بدون اینکه ما چیزی به پروتوتایپ اضافه کنیم اضافه شده پس یعنی __ali.__proto  برابر است با PersonProtoخب حالا یه سوال ، وقتی constructor نداریم پس چطور میتونیم وقتی یه آبجکت میسازیم مقدار دهی کنیم ؟باید بگم که بنا به نیاز میتونیم تابع constructor هم براش بسازیم و اسم دلخواهی بهش بدیم مثلا init  دقت کنید که اصلا شبیه اون تابع constructor نیست شاید ظاهرا فکر کنید همون کارو میکنه ولی کارایی اون رو نداره مثلا تابع constructor خود به خود صدا زده میشه ولی اینجا ما باید خودمون صداش بزنیمدر واقع تابع constructor شبیه سازی کردیمدقیقا مثل مثال زیرخب اینم از آخرین نوع ساخت شی توی جاواسکریپتتوی مقاله بعدی ارث بری رو توی هر سه نوع حالت، کامل بررسی میکنیمامیدوارم بدردت خورده باشه❤️کانال تلگرامم 👈 LeanByLearn@</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Mon, 22 Jul 2024 20:02:25 +0330</pubDate>
            </item>
                    <item>
                <title>شی گرایی قسمت چهارم (ES6 Class)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-es6-class-uxmv8kyvavgl</link>
                <description>همون طور که توی قسمت اول قبل گفتیم، به سه شکل میتونیم شی گرایی رو توی جاواسکریپت هندل کنیم که مورد اول رو توضیح دادم.توی این قسمت میخوایم مورد دوم، یعنی ES6 class رو بررسی کنیم.از ES6 به بعد سینتکس جدیدی برای هندل کردن شی گرایی توی جاواسکریپت معرفی شد، در واقع میخواستن که مثل بقیه زبون ها جاواسکریپت هم از کلیمه کلیدی class پشتیبانی کنه و کد هامون تروتمیز تر باشه اما این کلاس ها توی جاواسکریپت مثل کلاس های تو سایر زبان های برنامه نویسی (مثل ++C یا جاوا یا ...) نیستندر واقع فقط ظاهرش شیه class شده (در اصلاح بهش میگن syntactical sugar) ولی پشت قضیه همون شکل یک یعنی به صورت constructor function داره هندل میشه، پس اگه اون رو خوب متوجه شدید اینجا صرفا سینتکسش تغییر کردهدقیقا هرچیزی که توی constructor function صدق میکرد توی ES6 Class هم صدق میکنهتوی مثال زیر Person رو به دو روش نوشتیم و هردو دقیقا به یک شکل هستن با سینتکس متفاوت :اما وقتی از ES6 Class استفاده میکنی به نکات زیر توجه کن:☝نکته اول: توی بدنه class ها، کد ها همیشه strict mod اجرا میشن☝نکته دوم: class ها هم عین توابع first-class citizen هستن، یعنی چی؟یعنی مثل یک متغییر هم میشه return شون کرد و هم به توابع ارسالشون کرد☝نکته سوم: class ها مثل توابع hoisting نمیشن (توی این مقاله کامل hoisting رو شرح دادم) خیلی کوتاه بگم hoisting چیه ؟ مکانیزمی که متغییر ها ، توابع و .... رو به بالاترین سطح خودشون میبره و میتونیم قبل از تعریفشون بهشون دسترسی داشته باشیمالبته کلاس ها هم hositing میشن ها ولی  قبل کلاس قابل دسترسی نیستن و وقتی کد رو اجرا کنید به ارور میخورید، پس همون بگیم نمیشن بهترهمثال زیر رو ببینید اگه اجراش کنید به این ارور برخورد میکنیدReferenceError: Cannot access &#039;Person&#039; before initializationهمچنین ما میتونیم به دو صورت کلاس هارو بنویسیم//Class declarations
class Person { }

//Class expressions
const Person = class { }حالا ممکنه سوال پیش بیاد از ES6 Class استفاده کنیم یا constructor function ؟؟؟🤔ببینید به صورت عامیانه و خب غالبا از ES6 Class استفاده کنیم بهتره ولی(نظر شخصی) به شرطی که بدونیم پشت قضیه چه خبره، اینطوری هم میدونی چی کد میزنی هم میدونی اون پشت شی گرایی چطور داره هندل میشه و هم رفع باگ بهتری انجام میدی چون ES6 Class فقط یک سینتکس هستامیدوارم بدردت خورده باشه❤️کانال تلگرامم 👈 LeanByLearn@</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 28 Jun 2024 17:40:25 +0330</pubDate>
            </item>
                    <item>
                <title>شی گرایی قسمت سوم (prototype chain)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-prototype-chain-lovq8dx2un1a</link>
                <description>به قسمت سوم شی گرایی در جاواسکریپت خوش اومدیتوی این قسمت میخوایم در رابطه با زنجیره پروتوتایپ(prototype chain) حرف بزنیم و ببینیم چطور کار میکنهاگه  scope chain رو فهمیده باشید و باهاش آشنا باشید، prototype chain رو خیلی راحت تر میفهمیدتوی این مقاله راجع به scope chain کامل بحث کردیم. فقط تنها فرقش اینه اونجا دنبال اسکوپ یه متغییر میگشتیم اما این جا داریم دنبال method یا property میگردیمخب، از مقاله قبل به یاد دارید که هر آبجکت توی جاواسکریپت یک prototype داره، جاواسکریپت وقتی میخواد یک متد یا پراپرتی که شما صدا میزنید اجرا کنه میره تا دنبال اون متد یا پراپرتی بگرده و براتون اجراش کنهاما این جست و جو چطوری هست ؟ به سختی🙃وقتی شما به متد یا پراپرتی رو صدا میزنید جاواسکریپت میره توی پروتوتایپ دنبالش میگرده، در وهله اول توی خود ابجکت به دنبال اون method میگرده اگه بودش که هیچی اگه نبود میره یک مرحله بالا تر یعنی پروتوتایپ والدش میگرده، اینقدر میره بالا تر تا به null برسهاجزا بدین یک مثال بزنم و همزمان موقع خوندن عکس زیر رو هم نگاه کنید(منبع عکس PDF جوناس):این کد رو در نظر بگیرید:jonas.hasOwnProperty(&amp;quotname&amp;quot);خب آبجکت jonas ما که متدی به اسم hasOwnProperty نداره  پس چطور این کد اجرا میشه ؟🤔در وهله اول جاواسکریپت توی خود ابجکت jonas رو میگرده ببینه این متد هستش یا نه، میبینه ای دل غافل اینجا که نیستش پس چیکار کنیم ؟ میریم سر وقت _ _ proto _ _ و خب _ _ proto _ _ هم به چی اشاره(ارث بری) میکنه؟ آفرین، به Person.prototype پس میره یه مرحله بالاتر تا Person.prototype رو بگرده و ازش بپرسه آقا شما متدی با این hasOwnProperty  اسم داری ؟ اونم میگه نه متاسفانه🥲جاواسکریپت باز میره سر وقت _ _ proto _ _ و خب _ _ proto _ _ که داره به ایشون یعنی Object.prototype اشاره(ارث بری) میکنه، میره میپرسه آقای Object.prototype شما این متد رو داری hasOwnProperty  اونم میگه بله که دارم، پس جاواسکریپت میره و ازش استفاده میکنه و صداش میزنه، به همین راحتی، انقدر میره از بالاسری میپرسه تا متد یا پراپرتی مورد نظر رو پیداش کنهحالا فرض کنید Object.prototype هم متد hasOwnProperty  رو نداشت، اون وقت چی میشد ؟ هیچی null برمیگشت و میگفت اصلا چنین چیزی وجود ندارهکد زیر هم گویای همه چیزه :jonas.__proto__ 👉 Person.prototype
jonas.__proto__.__proto__ 👉 Object.prototype
jonas.__proto__.__proto__.__proto__👉 nullاین بحث رو همینجا تموم میکنیم تا خیلی طولانی نشه، امیدوارم لذت برده باشید❤️کانال تلگرامم 👈 LearnByLearn@</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 21 Jun 2024 18:37:26 +0330</pubDate>
            </item>
                    <item>
                <title>شی گرایی قسمت دوم (deep dive prototype)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-deep-dive-prototype-vu0osjnelwwr</link>
                <description>توی شی‌گرایی کلاسیک خب طبیعتا ما یک class داریم و هروقت از روی اون کلاس، object بسازیم میگیم عمل instantiation یا همون نمونه سازی اولیه رو انجام دادیم اما توی جاواسکریپت یه کوچولو جریان فرق داره🙃قبل شروع اینو در نظر داشته باشه که توی جاواسکریپت همه چی یک object هست حتی آرایه، حتی توابع و ...توی جاواسکریپت یه آبجکتی هست به اسم prototype و هر object ما یک پروتوتایپ داره که کامل توی این مقاله بهش میپردازیم☝️اگه این پروتوتایپ(خیلی مهمه) رو قشنگ درک کنید قول میدم شی‌گرایی جاواسکریپت براتون عین آب خوردن بشه و شاید این مبحث برای بار اول که بخونید گیج کننده باشه.این پروتوتایپ قصه ما شامل method و property هایی است که object هایی که به اون پروتوتایپ متصل شده اند می تونن به اون دسترسی داشته باشند و از اونا استفاده کنندیا به صورت عامیانه آقای x یک جعبه ابزار داره که پر از ابزار الاتی مثل پیچ گوشتی، آچار، چکش و ... اینا هست، اینجا آقای x که یک تعمیر کاره حکم object رو داره اون جعبه ابزاری که همیشه همراهشه حکم prototype رو داره و اون ابزار آلات حکم method و property رو دارن پس هرکس بخواد از اون متد ها و پراپرتی ها(ابزار الات) استفاده کنه کافیه پروتوتایپش رو (جعبه ابزار) رو به اشتراک بزارهبه این اشتراک گذاشتن چی میگن؟ prototype inheritance (ارث بری پروتوتایپ)، در واقع object ما نماینده(delegation) اون پروتوتایپ هستشنکته: ببینید توی بقیه زبان های برنامه نویسی وقتی یک کلاس از یک کلاس دیگه ارث بری میکنه تمام متد های کلاس والد توی کلاس فرزند کپی میشن ولی اینجا این اتفاق نمیوفته و کپی رخ نمیده بلکه delegation رخ میده، یعنی چی؟ یعنی object ما یک نماینده یا یک وکیل(delegate) از prototype هستش که شامل همه متد ها و پراپرتی های اون پروتوتایپ هست.میخوام که این نتیجه رو بگیریم این ارث بری با اون ارث بری که مقاله قبل گفتیم فرق داره ها حواستون باشه، توی اونجا دوتا کلاس از هم ارث بری میکردن ولی این جا یک آبجکت داره از کلاس ارث بری میکنههمون طور که توی عکس میبینیدوقتی شما از یک متد آرایه استفاده میکنید باید از prototype inheritance تشکر کنید، چون اونه که باعث میشه شما به اون متد های آرایه دسترسی داشته باشیدپس وقتی توی داکیومنت نوشته Array.prototype.map این قسمتش یعنی Array.prototype گویای اینه که هررر نوع آبجکتی که جنسش از آرایه باشه بتونه به اون متد ها دسترسی داشته باشه (همون مثال آقای x)اگه برید توی کنسول مرورگرتون Array.prototype رو بزنید کل متد های آرایه رو بهتون نشون میده و این متد ها توی prototype property هستن نه توی Arrayیه مثال بزنیم:وقتی تو اینو تعریف میکنی const numbers = [1,2,3] یعنی داری به جاواسکریپت میگی numbers یه نوع آرایه اس یعنی میتونه به تمام متد های آرایه دسترسی داشته باشه پس یعنی متدی مثل map توی numbers تعریف نشده بلکه توی Array.prototype تعریف شده و numbers به عنوان نماینده میتونه به اون متد ها دسترسی پیدا کنه (به وسیله __proto__ که جلوتر میگمش)خب به صورت کلی ما به سه شکل میتونیم شی گرایی رو توی جاواسکریپت پیاده سازی کنیم:1️⃣ شکل اول: constructor functionاین تکنیک شی مورد نظرمون رو از یک تابع میسازه، در واقع آبجکت هایی مثل Array و Set و... به همین شکل ساخته شدن2️⃣ شکل دوم: ES6 Classesاین نوع تکنیک مدرن شده شکل اول هستش و مثل یک پوسته روی شکل اول قرار گرفته یعنی درسته که از کلمات کلیدی class یا constructor استفاده میکنید ولی در پس قضیه همون شکل اول داره رخ میده3️⃣ شکل سوم: ()Object.createشاید بشه گفت ساده ترین و سر راست ترین راه لینک کردن یک آبجکت به prototype این راه باشهخب بریم سر وقت شکل اول یعنی constructor function (تابع سازنده)تابع سازنده هیچ چیز عجیبی نیست بلکه فقط یه تابع است مثل بقیه توابع با این تفاوت که با کلمه کلیدی new صداش میزنیم☝️نکته: همیشه اسم تابع سازنده اتون رو با حروف بزرگ بنویسید این یه قرار داد هست مثل همون Array  که جاواسکریپت هم از این قرارداد پیروی میکنه☝️نکته: برای ساخت تابع سازنده به هیچ وجه از arrow function ها استفاده نکنید چون this خودشون رو ندارن توی این مقاله راجع بهش نوشتم☝️نکته: بلافاصله بعد از ساخت ابجکت از تابع سازنده مورد نظر اتوماتیک خودش صدا زده میشه☝️نکته: وقتی میگیم تابع سازنده انگار همون کلمه class رو که توی بقیه زبان ها هست داریم به کار میبریم، درواقع شبیه سازی شده class عهبا یه مثال شروع میکنم، تابع سازنده زیر(که در واقع انگار همون class هست) قراره یک Person باشه و اسم و سن شخص توش ذخیره بشه، پس برای اینکه یه نمونه یا شی ازش بسازیم باید از new استفاده کنیمexample constructorحالا وقتی از کلمه new استفاده میکنید پس قضیه چهار اتفاق میوفته:1️⃣ اول: وقتی خط 6 رو مینویسید یک شی خالی به این صورت { } از Person ساخته میشه2️⃣ دوم: تابع صدا زده میشه و this به اون آبجکت ساخته شده خالی اختصاص داده میشه یعنی { } = this و اون پراپرتی های firstName و age براش set میشن3️⃣ سوم: حالا آبجکت { } ما لینک میشه به prototype یعنی proto__ : Person.prototype__ 4️⃣ چهارم: و در آخر شی که مرحله اول ساخته شده بود توسط تابع سازنده return میشه وشما قرار نیست چیزی رو return کنید (گفتم که خودش اتوماتیک اجرا میشه)دقیقا تابع سازنده ما نقش همون طرح ماشینی هست که توی مقاله قبلی راجع بهش حرف زدم، یعنی میتونیم از تابع سازنده امون کلی آبجکت متفاوت بسازیم مثل ali ، Mohammad ، sara و ....حالا اگه از متد instanceOf استفاده کنید میبینید که ali نمونه ای از Person هست یعنی console.log(ali instanceOf Person); 👉 trueخب تا اینجا ما برای کلاسمون پراپرتی ساختیم اما اگه بخواییم method بسازیم چطور میشه ؟حتما پیش خودت میگی خب مثل عکس زیر متد میسازیم دیگه،wrong methodاما سخت در اشتباهی هیچ وقت توی تابع سازنده ات method نساز،  میگی چرا ؟فرض کن از Person سیصد تا آبجکت ساختی، اینطوری عین سیصد تا آبجکتت شامل تمام اون متد ها هستن یعنی انگاری تو با سیصد تا ابجکت، سیصد بار اون همههه متد رو کپی کردی(نه فقط اون هایی رو که نیاز داری)، خب این حرکت پرفورمنس رو نابود میکنه، پس چیکار کنیم؟ اینجاست که باید از prototype و prototype inheritance استفاده کنیمخب همون طور که بالاتر گفتیم هر تابع سازنده یک پراپرتی داره به اسم prototype پس اگه بیاییم متد هامونو توی اون بسازیم چی میشه ؟😉در واقع تو با تعریف کردن متد هات توی پراپرتیه prototype یه ظرف میسازی که هر آبجکتی که از Person ساخته شد دست کنه تو اون طرف متد مورد نظرشو برداره استفاده کنه پس یعنی دیگه سیصد بار کپی نمیشه و هر آبجکت بنا به نیازش اون متد رو فراخونی میکنهیعنی اینطوری :حالا اگه کد زیر رو اجرا کنی عکس زیر مواجه میشیconsole.log(Person.prototype)میبینی متد sayName جز خود ابجکت نیست و وارد پروتوتایپ شده چون اون جا تعریف شدهما یک چیز دیگه ای به اسم __proto__  داریم که دقیقا همون prototype هست ولی برای آبجکت ها استفاده میشه پس اگه کد زیر رو بنویسیم باید خروجی true برگردونهali.__proto__ === Person.prototype 👉 trueدر واقع توی اون مرحله سوم بود(برو یه نگاه بهش بنداز) که __proto__ تعریف میشه و اشاره میکنه به Person.protoype ، اوکی؟😉 شما میتونید علاوه بر متد ها، پراپرتی ها رو از طریق Person.prototype اعلان کنید ولی دقت کنید که دیگه جز پراپرتی های مستقیم آبجکت نیستن و میرن زیر مجموعه __proto__  (دقیقا مثل sayName)و اونایی که جز پراپرتی های مستقیم آبجکتمون هستن، که توسط خود تابع سازنده تعریف بشن مثل همون age و firstName خود جاواسکریپت از طریق متد زیر میفهمه که چی جز چیهتوی مثال بالا چون lastName رو توی Person.prototypeتعریف کردیم پس جز پراپرتی های خود آبجکت نیستامیدوارم لذت برده باشید ❤️ مخلصیمکانال تلگرامم LearnByLearn@خلاصه ای از تمام چیزایی که گفتیم رو هم میتونید توی عکس زیر ببینید(منبع عکس از PDF های جوناس)</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 14 Jun 2024 21:43:27 +0330</pubDate>
            </item>
                    <item>
                <title>شی گرایی قسمت اول (چهار اصل شی گرایی در جاواسکریپت)</title>
                <link>https://virgool.io/codenevis/%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-%DA%86%D9%87%D8%A7%D8%B1-%D8%A7%D8%B5%D9%84-%D8%B4%DB%8C-%DA%AF%D8%B1%D8%A7%DB%8C%DB%8C-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-jjf0p3dypcsg</link>
                <description>توی این سری مجموعه مقالاتی که قراره منتشر بشه، میخواییم کلیک کنیم روی برنامه نویسی شی گرا و زیر و بم شو توی جاواسکریپت بریزیم بیرون، البته این مفاهیمی که توی این مقاله ازشون حرف میزنیم مختص به جاواسکریپت نیست و کلا مربوط به همه زبان هایی میشه که شی گرایی رو پشتیبانی میکنندر ضمن توی این مقاله کمتر کد میزنیم و تمامی کد ها شبه کد هستن و فقط برای انتقال مفهوم استفاده کردم کدزنی اصلی میمونه برای مقالات بعدیتوی برنامه نویسی چندین نوع الگو یا پارادایم(paradigm) داریم مثل برنامه نویسی تابعی(functional)، برنامه نویسی رویه ای(procedural)، برنامه نویسی شیءگرا(object oriented) و .... که هرکدوم خوبی و بدی هایی دارن اما خبر خوب اینه که جاواسکریپت از اکثرشون پشتیبانی میکنه و انعطاف زیادی دارهدر برنامه نویسی شی گرا ما یه مدل داریم که از دنیای واقعی یا غیر واقعی یا هرچی، ازش الگو برداری میکنیم و از این الگو میتونیم هزاران بار استفاده کنیم، در واقع یکی از مزیت های oop اینه که کد های شمارو reusable  یا قابل استفاده مجدد میکنهحالا توی oop ما با دو مفهوم اصلی به اسم شی(object) و کلاس(class) سر کار داریم، خب اصلا اینا چی هستن ؟ اجازه بدین با یه مثال پیش بریم:نکته: قبل شروع اینو بگم که جاواسکریپت چیزی به اسم class نداره و اگه میخوایی بگی از ES6 به بعد کلمه کلیدی class اضافه شده باید بگم بهت که اون فقط یه پوسته اس، در پس قضیه، جاواسکریپت بر اساس توابع و پروتوتایپ (prototype) شی گرایی رو هندل میکنهمقالات آینده کامل توضیحش میدمخب بریم سر اصل مطلب فرض کنید میخواین یه ماشین بسازین، خب اولین کار اینه که نقشه ماشین رو طراحی کنید که هربار خواستید یه ماشین بسازید از اون نقشه بار ها و بار ها استفاده کنید پس به اون نقشه و الگویی که میکشید میگن class و به اون ماشین یا ماشین هایی که میسازید میگن object، در واقع این کلاس ما یه نوع template هستحالا هر کلاس ما دوتا جز اصلی داره به اسم رفتار(behaviour) و صفت(attribute)، هر مشخصه از اون ماشین ما میشه یه صفت و هر چیزی که یک فعل(یعنی قابل انجام) باشه رو بهش میگن رفتار، برگردیم به مثالی که زدیم: ماشینی که داشتیم یک سری صفات داره مثل چرخ، مثل شیشه، ... و یک سری رفتار هم داره مثل بوق زدن، حرکت کردن، گاز دادن ....عکس و کد(کد های زیر شبه کد هستن) زیر گویای حرف هایی هست که تا الان زدیمclass Car {
        wheels
        window
        color

        bogh() {
                 //logic
         }

         gaz() {
                 //logic
         }

}ممکنه اسامی که بهتون گفتم به شکل های دیگه هم ببینید مثلا به شی یا آبجکت، instance هم میگنیا مثلا به صفت ممکنه بگن property و یا به رفتار بگن methodحالا چطور از روی کلاسمون شی بسازیم ؟ یا به قول معروف instantiate کنیم؟ کافیه تا با کلمه کلیدی new و بعد اوردن اسم کلاس یه شی جدید ازش بسازید(مقالات بعدی بیشتر وارد کد زدن میشیم فعلا بسنده کنید)const myCar= new Car();تا اینجا با شی گرایی و مفاهیم اصلیش آشنا شدین حالا بریم سراغ چهار اصل شی گرایی که جز ستون شی گرایی هستن که اگه بلدشون نباشید اصلا شی گرایی نمیدونیداصل اول 👈 انتزاع یا Abstraction :انتزاع به ما میگه که آقا جان اصلا مهم نیست برا من اون method یا رفتارت چطور پیاده سازی میشه بلکه اون کلیت کار مهمه یعنی مثلا تو توی متد بوق زدن موظفی که بوق بزنی حالا مهم نیست چطور میخوایی بوق بزنی در نهایت من ازت یه بوق میخوام و موظفی که متد بوق رو پیاده سازی کنیاز این اصل توی اینترفیس(سرچ کن اگه نمیدونی چیه) نوشتن به کررات استفاده میشه در واقع این اصل کمک میکنه که  جزعیات پیاده سازی پنهان بمونه و کد رو تمیز تر و قابل استفاده مجدد تر(همون reusable) بکنهگوشی موبایلتو در نظر بگیر فقط یه صفحه نمایش میبینی و یه چندتا دکمه ولی در اصل کلی سیم پیچی و منطق پشت تلفنه که تو ازش بی خبری و این یعنی اصل انتزاعتوجه کنید کلاس هایی که ابسترکت هستن رو نمیتونید ازشون شی بسازید بلکه اونا فقط مثل یه نوع قرار(interface) داد میمونن که موظف هستید از اونا پیروی کنید و پیاده سازیشون کنیدنکته: جاواسکریپت به صورت built-in کلمه کلیدی یا چیزی برای پیاده سازی انتزاع نداره و باید از تایپ اسکریپت استفاده کنید.گرچه trick یا ترفند هایی وجود داره که بشه پیاده سازی کرد ولی به نطرم از تایپ اسکریپت استفاده کنید تمیز ترهاصل دوم 👈 کپوسوله سازی یا Encapsulation:این اصل با زبون بی زبونی میگه  متد ها و پراپرتی ها فقط از توی کلاس قابل دسترسی باشن و کلاس های دیگه نتونن بهش دسترسی داشته باشن مگر اینکه توعه برنامه نویس ذکر کنی چی private باشه و چی publicخب اصلا چرا این اصل هستش به چه درد میخوره؟  باعث میشه که کد های خارجی توی کلاس های دیگه وضعیت و یا صفات داخلی کلاس مون رو نتونن تغییر بدن و باعث ایجاد side effect بشن و علت دیگه اینکه میتونیم خیلی راحت کد های داخل کلاس رو تغییر بدیم بدون اینکه کد های خارج کلاس دست خوش تغییر بشن و باگ تولید کنننکته: باز هم جاواسکریپت به صورت built-in اینو ساپورت نمیکنه و باید از روش های قرار دادی مثل گذاشتن _ پشت متد یا پراپرتی اعلام کنیم که این عضو private هستن.  البته تو آپدیت های جدید پرایوت با علامت # اضافه شده ولی خب ممکنه مرورگر های قدیمی از حتی جدید ساپورت نکنن ولی باز هم پیشنهاد من استفاده از تایپ اسکریپت هست چون کاملا ساپورت میشهاصل سوم👈 ارث بری یا Inheritance:اجازه بدین اینو با یه مثال توضیح بدم تا بهتر جا بیوفته فرض کنید تو سایتتون یه کلاس User دارید و طبق سیاست های سایتتون دو نوع کاربر هم دارید یکی admin و یکی کاربر عادی، خب حالا سوالی که مطرح میشه اینه که آیا باید برای ادمین هم که نوعی User هست کلاسی شبیه User بسازیم؟ به نظرتون اینطوری دوباره کاری نمیشه؟خیلی از ویژگی های ادمین و کاربر عادی مثل هم هستن پس عقلانی نیست دوباره یه کلاس ادمین بسازیم با همون ویژگی های User، پس چکار کنیم؟ کافیه که از ارث بری استفاده کنیدبرای اینکار کافیه از کلمه کلیدی extends استفاده کنید و بعد از اون اسم کلاسی رو بیارید که قراره به ارث برده بشه، جاوااسکریپت اینبار دیگه ازش پشتیبانی میکنه😏 به کلاس User میگن کلاس والد و به کلاس Admin میگن کلاس فرزندکد زیر رو ببین:کلاس ادمین تمام متد و پراپرتی های کلاس یوزر رو به ارث برده و علاوه بر اون ها(به شرط اینکه overwrite نشده باشن)، متد و پراپرتی های خودشو داره، چون مثلا کاربر عادی نباید بتونه کاربرای دیگه رو حذف کنه درسته؟class User {
          username
          password
          email

          login(password)   {            //logic         }
         sendMessage(msg)   {            //logic         }
 }

class Admin extends User{ 
          permissions
          deleteUser(userId)   {            //logic         }
}اصل چهارم👈 چندریختی یا Polymorphism:این اصل ممکنه یه خرده پیچیده باشه ولی فعلا خیلی ساده بیانش میکنیم و وارد جزعیاتش نمیشیماین اصل میگه که کلاس های فرزند(مثل همون Admin) میتونن متد های کلاس های والد رو overWrite کنن یعنی تغییرشون بدیم، مثلا فرض کنید متد login توی کلاس User پیاده سازی شده و ما میخواییم توی کلاس Admin لاگین امون یه طور دیگه ای باشه یا اصلا یه چیزی بهش اضافه کنیمدر واقع داریم میگیم یه نوع ریخت دیگه داریم بهش میدیماین بود از مفاهیم پایه شی گرایی که حتما باید راجع بهش اطلاع داشته باشید و پیش نیازه مقاله بعد هستشتوی مقالات بعد شی گرایی رو اختصاصی توی جاواسکریپت مورد بررسی قرار میدیمامیدوارم مقاله مورد پسندتون بوده باشه و استفاده کرده باشین.❤️کانال تلگرامم 👈 LearnByLearn@</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Thu, 06 Jun 2024 15:21:37 +0330</pubDate>
            </item>
                    <item>
                <title>Async در مقابل Sync</title>
                <link>https://virgool.io/codenevis/async-%D8%AF%D8%B1-%D9%85%D9%82%D8%A7%D8%A8%D9%84-sync-myk0uh1dmriy</link>
                <description>سلام توی این مقاله قراره بیشتر مفاهیم رو توضیح بدیم و خیلی کمتر دست به کد میشیم ولی هرجا که نیاز باشه کد هم یه مقدار گفتم.اول ببینیم فرق (Non-Blocking)Asynchronous و (Blocking)Synchronous چیه ؟برنامه نویسی همزمان یا همون Synchronous به این معنی هستش که کد هایی که مینویسیم خط به خط اجرا بشن، یعنی چی خط به خط ؟؟؟ یعنی هر خط کد منتظر میمونه تا خط قبلی انجام بشهپس شاید براتون قابل حدس باشه، مشکلی که اینجا به وجود میاد اینه که در برنامه نویسی همزمان اگه یه خط کد ما خیلیییی طول بکشه موجب کند شدن و فاجعه به بار اومدن بشه و باعث انسداد یا block شدن کد های ما بشهمثال زیر رو ببینید:توی این مثال کد ها خط به خط اجرا میشن یعنی اول line 1 چاپ میشه بعد line 2 چاپ میشه و بعدش تابع ()myFunction اجرا میشه و در آخرم line 4حالا اگه این تابع ما یه عملیات ریاضی سنگین داشته باشه و خیلی طول بکشه باعث انسداد و کند شدن برنامه ما میشهconsole.log(&amp;quotline 1&amp;quot);
console.log(&amp;quotline 2&amp;quot);
myFunction();
console.log(&amp;quotline 4&amp;quot);خب، بریم سراغ برنامه نویسی Asynchronous یا همون ناهمزمان ؟؟؟توی این نوع برنامه نویسی برخلاف Synchronous کد های ما خط به خط اجرا نمیشن بلکه، این نوع کد ها در پس قضیه(توی background) run میشن و وقتی که تموم شدن  execute میشنپس دیگه ما صبر نمیکنیم تا خط به خط کد اجرا بشه و بعد بریم خط بعدیبریم یه مثال بزنیم و قابلیت Async رو شبیه سازی کنیم تا بهتر متوجه اش بشیم:const p = document.querySelector(&amp;quot.p&amp;quot);
setTimeout&#40;(&#41; =&gt; {
        p.textContent = &amp;quotcode time&amp;quot
}, 5 * 1000);
document.body.style.backgroundColor = &amp;quotred&amp;quotجاوااسکریپت به خط اول میرسه و اجراش میکنه و بعد میره جلوتر و میرسه به تابع setTimeout و خب ما بهش گفتیم بعد از 5 ثانیه اجرا بشه پس میره تو بک گراند تا کاراش تموم بشه و وقتی که تموم شد خروجی رو برگردونه و به ما نشون بدهدر واقع جاوااسکریپت بهش میگه خب اقای setTimeout  تو کارت طول میکشه، پس من میرم خط های بعدی رو اجرا میکنم و تو هر وقت که کارت تموم شد منو خبر کن تا خروجی رو به کاربر نمایش بدمو بعدش میره خط آخر ور اجرا میکنهپس چی شد ؟؟؟پس قضیه ترتیب اجرای کد ها اینطوری اجرا میشه:const p = document.querySelector(&amp;quot.p&amp;quot); 
document.body.style.backgroundColor = &amp;quotred&amp;quot
setTimeout&#40;(&#41; =&gt; { 
       p.textContent = &amp;quotcode time&amp;quot
 }, 5 * 1000); اول تگ p رو میگیره و بعدش بکگراند رو قرمز میکنه و در آخرم بعد از 5 ثانیه عبارت code time رو توی تگ p میزارهحالا اصلا این Asynchronous به چه درد میخوره؟ خب همون خط به خط کد هامون اجرا بشن دیگه، مشکلش چیه ؟؟؟ با یک مثال ساده توضیحش میدم که مشکل از کجا آب میخورهفرض کنید وارد یک سایت شدید و اون سایت میخواد یک عکس رو به همراه محتواش به شما نمایش بده و کل کد های js ما هم به صورت sync هستشخب درخواست ما میره سمت سرور که عکس و متن هارو نمایش بده ولی چون اینترنت ما خیلی ضعیفه خیلی طول میکشه که عکس بخواد load بشه و چون کد های ما sync هستن تا وقتی عکس لود نشه مطالب بعد نمایش داده نمیشن یعنی به خاطر یک عکس کل کد های ما مسدود شده و اجرا نمیشن و چیزی به کاربر نمایش داده نمیشهاما اگه اون کد قسمت ارسال درخواست برای لود کردن عکس ما به صورت Async باشه چی؟؟ مشکل ما حل میشه😉در واقع میگه تو فعلا بقیه اطلاعات رو به کاربر نمایش بده وقتی عکس load شد اونم برات نمایش میدم. این load عکس حکم همون setTimeout رو دارهاما بریم عمیق تر بشیم ببینیم چطور این کد های ما پس قضیه جاوااسکریپت اجرا میشن ؟؟🤔اصلا مگه نمیگن جاوااسکریپت تک نخی (single thread) هست پس چطور کد های ما non-blocking داره اجرا میشه ؟؟ 🤔همون طور که توی سری مقاله های اندر احوالات جاوااسکریپت(کل قسمت هاش توی پروفایلم هست) توضیح دادم، Engine جاوااسکریپت شامل بخش هایی میشه که خلاصه اش رو به همراه توضیحات مختصرش توی عکس زیر میتونید ببینید:توی مقاله های قبل(قسمت اول) راجع به همه اجزای عکس بالا مفصلا توضیح دادماما راجع به Callback Queue توضیح خاصی ندادیم اما الان میخواییم بریم بشکافیمش🔪کد توی عکس بالا رو ببینید، ابتدا js خط اول و دوم رو وارد call stack میکنه اجرا میشن و میرن بعد میرسه به خط سوم(eventListener) و هفتم(fetch) و چون این دوتا عملیات async هستن و مربوط به web api هستن js به call stack میگه: آقای call stack این دوتا قطعه کد async هستن پس توی بکگراند انجامشون میدم و وقتی تموم شدن، نتیجه رو میفرستم برات، حالا یا این نتیجه با موفقیت انجام شده(resolve) یا شکست خورده(rejected)اینجاست که Callback Queue  به همراه event loop به میدون میاد، همون طور که از اسم callback queue پیداس، یک صفی از callback ها هستش که به ترتیب اولویت ورودشون، خارج میشنتوی Callback Queue کالبک هایی هستن که قرار بود جی اس پس قضیه هندلشون کنهحالا event loop مرتب به callstack نگاه میکنه ببینه خالی هست یا نه، اگه خالی باشه سریعا یه دونه کالبک(طبق اولویت) از Callback Queue میگیره و میفرسته توش تا execute بشه (نه run)کجاکد ها run میشن؟عکس بالا رو ببین،توی web apiنکته: کلا کار هایی مثل ارسال درخواست ها(request)، ajax، DOM، تایمر ها و ... به صورت async توی web api انجام میشه در نتیجه این ها جز خود js نیستن بلکه جز web api مرورگر هستن نکته: توی js چیزی به صورت Async اجرا نمیشه، اصلا js  درکی از time و اینا نداره که(چرا؟) چون توی Engine جاوااسکریپت اعمال Async رخ نمیده بلکه خود runtime و callback queue و سایر موارد کار های async رو انجام میدن، اصلا non-blocking علتش همین اجزایی هست که نام بردیمنکته: فکر نکنید هر وقت اسم callback اومد به صورت async اجرا میشه ها، مثلا کالبک توی تابع map به صورت async نیستش کهنکته: برای نوشتن کد async باید قبل اسم تابع کلمه async رو بزاریم و داخل تابع از await استفاده کنیم، توی این مقاله راجع به نوشتن کد حرف نمیزنم بلکه اینکه چطور کار میکنه بحث میکنیم ولی گفتم یه hint این وسط بدمخب یه خلاصه بگیم ببینیم چه اتفاقاتی تا اینجا افتاد: وقتی کل کد اجرا میشه،js میره سراغ load کردن img و fetch کردن داده ها و  وقتی load عکس تموم شد وارد callback queue میشه و event loop هم میفرستتش به call stackاما قضیه fetch چی میشه؟؟ایا اونم مستقیما کارش که تموم شد میره توی callback Queue ؟؟ نه زهی خیال باطل. عه !!! چرا؟ مگه عملیات async نیست پس چرا نمیره توی صف ؟؟چون fetch یه پرامیس (آخر مقاله توضیح کوتاهی دادم که پرامیس چیه) بر میگردونه و پرامیس هام چون قلدر ترن صف جداگونه خودشون رو دارن که از قضا به صف callback Queue تقدم داره، اسم این صف که مخصوصا برای پرامیس ها ساخته شده Microtasks Queue هستش و fetch قصه ما میره توی اون و زود تر از load img انجام میشهبه طور خلاصه ترتیب اولویت اجرا توسط event loop اینطوری هست:Sync code -&gt; Microtask Queue -&gt; Callback Queueپس event loop همیشه اول microtask queue رو چک میکنه بعد callback queueبیا تا بهث اثبات کنم، کد های زیر رو ببین:console.log(&amp;quotline 1&amp;quot);

setTimeout&#40;(&#41; =&gt; {
        console.log(&amp;quotline 2&amp;quot);
}, 0);

Promise.resolve(&amp;quotline 3&amp;quot).then((res) =&gt; console.log(res));

console.log(&amp;quotline 4&amp;quot);به نظرت خروجی چیه؟؟؟اول کد های sync اجرا میشن یعنی خط اول و آخر و بعدش پرامیس و بعدش هم تابع setTimeoutپس خروجی میشه line 1
line 4
line 3
line 2اینکه پرامیس ها چی هستن و چطور کار میکنن خیلی میشه مفصلا راجع بهش بحث کرد ولی خیلی خلاصه بگم پرامیس ها ابجکت هایی هستن که قراره در آینده یه مقداری رو تحویل ما بدن، حالا این مقدار میتونه موفقیت آمیز باشه یا غیر موفقیت آمیز که در اصطلاح به ترتیب بهشون میگن resolve و rejectاینکه چطور کار میکنن و چطور مینویسمشون رو دیگه توی این مقاله نمیشه گفت چون خیلی زیاد میشهامیدوارم به دردتون خورده باشه❤️ یا حق</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Tue, 14 May 2024 11:12:17 +0330</pubDate>
            </item>
                    <item>
                <title>شیرجه عمیق به قلب Closure در جاواسکریپت</title>
                <link>https://virgool.io/codenevis/%D8%B4%DB%8C%D8%B1%D8%AC%D9%87-%D8%B9%D9%85%DB%8C%D9%82-%D8%A8%D9%87-%D9%82%D9%84%D8%A8-closure-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-tze3cbsnvbok</link>
                <description>مبحث کلوژر توی جاوااسکریپت شاید یکی از مواردی باشه که درکش سخت باشه (شایدم من اینطور حس میکنم🤷🏻‍♂️)به هرحال آسون یا سخت شما باید قبلش این مواردی رو که لیست میکنم آشنا باشید تا بهتر درکش کنیدExecution Context - Scoping - High Order functionدوتای اولی رو کاملا مفصل توی سری مجموعه اندر احوالات جاوااسکریپت توضیح دادم پس اگه نخوندینش یه سری بهش بزنید، پشیمون نمیشید😉اون سومی یعنی High Order function رو الان براتون توضیح میدم بعدش میریم که قلب کلوژر رو بشکافیم😈خب، ببینیم High Order function چیه ؟؟؟🤔من دوتا تعریف ناب بهتون میگم که بحثو جمعش کنیم1️⃣ به تابعی که تابعی را به عنوان آرگومان ورودی دریافت میکنه، میگیم high order functionconst sayHello = () =&gt; consloe.log( &#039; salam malikom &#039; );
button.addEventListener(&#039; click &#039;, sayHello);الان addEventListener میشه high order function ما و sayHello میشه تابع callback ما2️⃣ تابعی که یک تابع جدید رو برگردونه(return کنه) رو هم باز یک High order function می نامیم.const counter = function() {
    let count = 0;

    return function() {
        count++;
    }
}توی مثال بالا تابع counter میشه high order function ماممکنه سوال پیش بیاد برات مگه تابع، یه مقدار یا value هستش که تو به عنوان آرگومان پاسش میدی یا بر میگردونیش از یه تابع ؟؟؟باید بگم به لطف مفهوم first class function ها بلهمفهوم first class function میگه که جاوااسکریپت با توابع مثل شهروندان درجه یک (first class citizens) برخورد میکنه یعنی توابع رو به شکل یک value یا مقدار در نظر میگیره به همین علته میتونیم به عنوان آرگومان به تابع پاسشون بدیم یا return شون کنیم و در آخرم این رو یادتون نره که توابع هم نوعی object هستن، درواقع همه چیز تو جاوااسکریپت یه آبجکت محسوب میشه حتی آرایه هم نوعی آبجکتهخب دیگه پیشنیاز هارو یاد گرفتید حالا بریم سر وقت بحث اصلیمون یعنی کلوژراول ببینیم مشکل از کجا شروع میشه ؟؟؟☝🏻یه نکته بگم توی بحث یادگیری، اونم اینکه همیشه یه مفهوم رو خواستید درک کنید بفهمید از خودتون بپرسید که چرا اون مفهوم یا ویژگی به وجود اومده؟؟ اصلا اومده چه مشکلی رو حل بکنه ؟؟؟ اینطوری دیگه میدونید کی و کجا ازش استفاده بکنید. اوکی ؟تابع زیر رو در نظر بگیرید (مثال counter معروفترین مثال) ما میخوایم توی تابع زیر با هربار فراخوانی counter مقدار count رو افزایش بدیمconst counter= function() {
	let count = 0;
        count++;
  return count;
}

console.log(counter()); 👉🏻 1
console.log(counter()); 👉🏻 1
console.log(counter()); 👉🏻 1ولی خروجی با هر بار صدا زدن تابع counter میشه 1 و هیچی اضافه نمیشه به نظرت علتش چیه ؟؟؟دقیقا اینجاست که گفتم باید اون سه مورد پیشنیاز رو بلد باشید، علتش اینه که هربار تابع صدا زده میشه یک Execution context براش ساخته میشه و وارد call stack میشه و با return شدن، تابع از call stack خارج میشه پس این وسط چون count ما توی اسکوپ counter هست با نابود شدن تابع counter ، اونم از بین میره.پس راه حل چیه ؟؟؟راه حلش اینه که بیاییم count رو بیرون از اسکوپ تابع یعنی توی Global scope تعریف کنیم تا هر بار تابع وارد call stack میشه و ازش خارج میشه، count ما ازبین نره یعنی اینطوری 👇🏻let count = 0;
const counter= function() {
      count++;
  return count;
}

console.log(counter()); 👉🏻 1
console.log(counter()); 👉🏻 2
console.log(counter()); 👉🏻 3مشکل حل شد ؟؟ معلومه که نه اومدی چشمشو درست کنی ابروشو کج کردی ، فرض کن من یه تابع دیگه دارم که با count کار میکنه و یه دوتا ازش کم میکنه اون وقت چی ؟؟؟ اینطوری هر تابعی از راه برسه میتونه روی count تاثیر بزاره و عملا مفهوم pure function و side effect رو تحت تاثیر قرار میده (این دوتا رو سرچ بکنید اگه دوست داشتید)اینجاست که کلوژر به وجود اومد و عین سامورایی ها مشکل رو حل کرداجازه بدین به صورت داستان گونه توضیحش بدم تا بهتر براتون جا بیوفته، تصویر زیر رو میون توضیحاتم داشته باش*️⃣ در ابتدا به ساکن جاوااسکریپت به () const booker = secureBooking میرسه و اسکوپ و Global Execution context رو میسازه*️⃣ حالا تابع ()secureBooking صدا زده شده و js وارد بدنه اون میشه و Execution Context مربوط به booker رو میسازه و همچنین passengerCount که مقدارش صفر هست رو توی Execution Context ساخته شده میزاره*️⃣ الان js رسید به return پس تابع ()secureBooking از call stack خارج میشه و تابع داخلی (یعنی همونی که return شده) به متغیر booker اختصاص داده میشه و وارد call stack میشه که empty هم هستشتا اینجا همه چیز عادی و طبق اون پیشنیاز هایی که گفتم پیش رفت و نکته خاصی نداشت، اما یه سوال پیش میاداصلا چطور تابع ()booker به متغیر passengerCount دسترسی داره ؟🤔 مگه تابع ()secureBooking که صاحبش بود از بین نرفت ؟🤔 مگه نباید متغیرشم با خودش از بین میبرد ؟🤔اینجاست که شیر میدون یعنی کلوژر وارد میشه، از اینجا به بعد کارا میوفته دست کلوژر برو که بریم :کلوژر یه راز مهم داره که میگه :☝🏻هر تابع (منظور تابع درونی هست یعنی همونی که return شده) همیشه به متغیر ها (Environment Variable) های Execution Context  ساخته شده توسط تابع بیرونی (بیرونی منظورمون تابع ()secureBooking ) دسترسی دارد حتی اگر تابع بیرونی از بین برود (یعنی از call stack خارج شود)پس توی مثال ما تابع booker همیشه به متغیر های ()secureBooking دسترسی داره حتی با اینکه ()secureBooking از کال استک خارج شده و از بین رفتهپس به این اتصال passengerCount  با تابع داخلی میگن کلوژر، اصلا از معنی فارسیش هم که میشه بستار معلومه که یه محیط بسته و ایزوله داره تولید میکنه و دیگه اون دوتا مشکل اول رو نداریمحالا بریم اون اولین مثال رو با کلوژر پیاده سازی بکنیم :const counter= function() {
  let count = 0;

return function () {
        count++;
        console.log(count);
    }
}

const x = counter();
x(); 👉🏻 1
x(); 👉🏻 2
x(); 👉🏻 3درآخر چندتا نکته بگم :☝🏻 کلوژر یه مفهومه، یعنی چیزی نیست که تو برنامه نویس بخوایی دستکاریش کنی بلکه خود js این کارو میکنه برات☝🏻اگه console.dir(x) بگیری توی کد بالا میتونی تصویر زیر رو ببینی و این نتیجه رو بگیری که قبل از اسکوپ و گلوبال، تابع برای پیدا کردن متغیر، اول کلوژر رو سرچ میکنه پس کلوژر بر اون دوتا مقدم هستش (نکته کنکوری هست)بعید بدونم دیگه مشکلی با کلوژر داشته باشی 😌 چون کامل شکافتیمشامیدوارم بدرتون بخوره و اگه از این دست مطالب دوست داری، توی کانال تلگرامم عضو شو LearnByLearn@</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 22 Mar 2024 14:43:31 +0330</pubDate>
            </item>
                    <item>
                <title>اندر احوالات جاوااسکریپت (قسمت پنجم)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%A7%D9%86%D8%AF%D8%B1-%D8%A7%D8%AD%D9%88%D8%A7%D9%84%D8%A7%D8%AA-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D9%82%D8%B3%D9%85%D8%AA-%D9%BE%D9%86%D8%AC%D9%85-zcjp8hhrr2cf</link>
                <description>javascriptآنچه گذشت :توی این مقاله گفتیم Execution Context ما سه قسمت داره که دوتاشو (scoping و  Variable environments ) رو مفصل توضیح دادیمتوی این قسمت به آخرین مبحث یعنی this میپردازیم و پرونده Execution Context رو میبندیمیه جمله راجع به this میگم ، اگه اینجمله رو درک کنید قضیه this براتون بسته میشه(قول میدم🙂):☝🏻 کلیدواژه this یک متغیر خاص هست که به ازای هر Execution Context ایجاد می شود یادته به ازای هر تابع که صدا زده میشد یک Execution Context داشتیم ؟؟؟ پس میشه نتیجه گرفت که کلمه this یک متغیر خاص هست که به ازای هر تابع ایجاد می شود پس کلیدواژه this  به صاحب تابع اشاره میکنه (این جمله خیلی خیلی مهمه) یا در اصطلاح میگن binding☝🏻حواست باشه this به خود تابع اشاره نمیکنه هااا بلکه به صاحب اون تابع(یا method) اشاره میکنه حالا که مفهوم this رو درک کردین بریم عمیق تر بشیم ببینیم this توی حالت های متفاوت چکار میکنه1️⃣ کلیدواژه this در توابع :توی یه تابع عادی که توی فضای گلوبال تعریف میکنیم :اگه بدون strict mode اجراش کنیم صاحبش میشه کی ؟؟؟ آفرین، میشه آبجکت windowگفتیم this به صاحب تابع اشاره میکنه پس اینجا صاحب تابع showThis میشه آبجکت گلوبال window (البته توی مرورگر نه nodejs، توی رانتایم نود this به آبجکت گلوبال اشاره میکنه برو مقاله اول رو بخون)اگه با strict mode اجراش کنیم چی ؟؟؟ جواب میشه undefined (همیشه سعی کنید مود strict فعال باشه)&#039;use strict&#039;;
function showThis(){
    console.log(this);
};
showThis(); 👉🏻 undifined
--------------------------------------------------------------------------------------------
function showThis(){
    console.log(this);
};
showThis(); 👉🏻 window object2️⃣ کلیدواژه this توی method ها :توی متد ها اون آبجکتی که متد مورد نظر رو صدا زده میشه صاحب this مادوباره برمیگردیم به اون جمله ای که اول گفتم، صاحب متد کیه (یا کی اون متد رو صدا زده)؟؟؟ آبجکت Person پس مقدار (یا صاحب) this میشه Personconst Person = {
    firstName: &#039;Reza&#039;,
    lastName: &#039;Rezai&#039;,
    age: 1990,

    calculateAge() {
        return 2024 - this.age;
    },
};

console.log(Person.calculateAge()); 👉🏻 34در واقع return 2024 – this.age توی پس قضیه اینطوری میشه return 2024 – person.age3️⃣ کلیدواژه this توی Event Listener ها :توی این مورد this ما اشاره میکنه به اون المنتی که EventListener روش صدا زده شدهیعنی صاحب this ما توی مثال المنت Button هسbutton.addEventListener( &#039; click &#039; , function () {
    console.log(this);
});4️⃣ کلیدواژه this توی Arrow Function ها :اینجا دیگه جریان فرق میکنه، این نوع توابع this  ندارند یا بهتره بگم this مربوط به خودشونو ندارنپس چطور میشه ؟؟؟طبق گفته سایت MDN این توابع this عه نزدیکترین زمینه (context) یا اسکوپی که تابع توش تعریف شده رو میگیرندر اصلاح میگن این توابع دارای lexical this هستن به این معنی  که مقدار this آنها توسط محدوده اطرافشان (surrounding) تعیین می شودبه زبون عامیانه تر توی این نوع توابع  thisعه والد رو میگیرهکد زیر گویای همه چیزه# regular function
&#039;use strict&#039;;
function showThis(){
    console.log(this);
};
showThis(); 👉🏻 undifined
----------------------------------------------------------
# arrow function
&#039;use strict&#039;;
const showThis = () =&gt; {
    console.log(this);
};

showThis(); 👉🏻 window objectهمون طور که کد بالا قسمت arrow function رو میبینید چون this خودش رو نداره پس میره به context ایی که توش هست یا اسکوپی که توش هست (همون والدش) میگه :دستم به this ات ، این this تو بده ما استفاده بکنیم، والدش هم که آبجکت گلوبال window هست this اش رو میده دستشمثال دوم رو هم میزنیم که بری و راضی باشی:window.myName = &#039;mohammad&#039;;
const user = {
    myName : &#039;ali&#039;,
    hello: () =&gt; {
        return &#039;Hello &#039; + this.myName ;
    },
};

console.log(user.hello()); 👉🏻 Hello mohammadتوی کد بالا ما دوتا آبجکت داریم که پراپرتی myName رو دارن یعنی window (که آبجکت گلوبال) و userخب چون متد ما از نوع arrow function هستش میاد this والد یا نزدیکترین اسکوپ که حاوی myName هست رو میگیره و نمایش میده یعنی myName که صاحبش آبجکت گلوبال window هستدر واقع اصلا به آبجکت user نگاه هم نمیندازه 😞حالا اگه همین متد رو با تابع regular بنویسی میاد ali رو برات چاپ میکنه (خودتون تست بزنید)☝🏻اگه میخوایی برای آبجکتت متد بنویسی سعی کن از arrow function استفاده نکنی❗اگه براتون سوال پیش اومده که چرا  به جای اون window.myName = mohammad ننوشتیم   const myName = mohammad به این علته که ما میخواییم اون myName پراپرتی عه آبجکت window باشه تا arrow function وقتی میره اسکوپ بالاترش رو جست و جو میکنه اونو پیدا کنهپس اگه با const تعریفش کنیم جز پراپرتی های آبجکت  window نیست و فقط یه متغیره معمولیه و undefined خروجی میشه چون تابع arrow هرچی گشته چیزی برای this پیدا نکرده بنده خدا 🙂خب حالا فرض کنید ما خودمون میخواییم تعیین کنیم که چه متدی به کدوم آبجکت متصل بشه و this اش رو بگیره، اینجاست که سه تفنگدار به اسم bind و call و apply وارد بازی میشنبا این سه تا ما میتونیم صاحب this رو دستکاری کنیم و خودمون تعیین کنیم چی باشهمن توی این مقاله فقط به bind میپردازم چون کاربردی تره ولی اون دوتام تقریبا با تفاوت کم عین همینن ولی کلا مفهومشون با bind یکیه.متد bindتابعی درست می‌کنه که مقدار this توی اون به یک آبجکت مشخص و تعیین‌شده‌ای اشاره می‌کنه که ما براش تعیین کردیم پس  این تابع (یعنی تابعی که bind ساخته) همیشه به اون thisیی اشاره می‌کنه که ما براش تعیین کردیمconst yourNewMethod = yourMethod.bind(yourObject);
yourNewMethod ()برای اینکه یادتون بمونه به صورت عامیانه اینطوری به خاطر داشته باشید که اون yourMethod یه بازیکن فوتباله و bind هم یه دلال و yourObject هم یه تیم فوتبال 😁 حالا داستان رو گوش کن کاری میکنم هیچوقت یادت نرهبازیکن(yourMethod ) میاد پیش دلال(bind) میگه من میخوام یه تیم(yourObject) انتخاب کنم دلال(bind) میگه باشه تو یه تیم(yourObject) انتخاب کن تا من بچسبونمت (بایندت کنم) به اون تیم⚽حالا بیا رو مثال :const bazikon = function () {
    console.log(this.yourTeam);
};
----------------------------------------------------
const sepahan = {
     yourTeam: &#039;sepahan&#039;,
};
----------------------------------------------------
const esteghlal = {
    yourTeam: &#039;esteghlal&#039;,
};
----------------------------------------------------
window.yourTeam = &#039;Team Meli&#039;;
----------------------------------------------------
const bindSepahan = bazikon.bind(sepahan);
const bindEsteghlal = bazikon.bind(esteghlal);
----------------------------------------------------
bindSepahan();
bindEsteghlal();واقعا فکر نکنم دیگه توضیح بخواد نه ؟؟؟اگه نگرفتی چی شد توی کامنتا بگو بیشتر برات توضیح بدماگه خوشت اومد و دوست داشتی توی کانال تلگرامم عضو شو LearnByLearn@ مقاله های بعدی هم دیگه تحت عنوان اندراحوالات جاوااسکریپت منتشر نمیشن بلکه به اسم خود موضوع منتشر میشنامیدوارم بدردت خرده باشه ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 15 Mar 2024 22:53:17 +0330</pubDate>
            </item>
                    <item>
                <title>اندر احوالات جاوااسکریپت (قسمت چهارم)</title>
                <link>https://virgool.io/codenevis/%D8%A7%D9%86%D8%AF%D8%B1-%D8%A7%D8%AD%D9%88%D8%A7%D9%84%D8%A7%D8%AA-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D9%82%D8%B3%D9%85%D8%AA-%DA%86%D9%87%D8%A7%D8%B1%D9%85-azub6itrhapv</link>
                <description>خب خب ما هنوزم توی Execution Context گیر کردیمتوی مقاله قبل به یکی از اون سه موردی که توی Execution Context بود یعنی scope مفصل پرداختیمحالا توی این مقاله به مورد variable environment که یه جورایی Hoisting میشه میپردازیمخود کلمه Hoisting به معنی بالابردن هستش یعنی  یک متغیر به بالاترین سطح (Top-level)  scope خودش بره یا اصطلاح خارجیش میگیم variables lifted to the top of their scopeیعنی اگه variable، function و class داشتی اینا به بالاترین سطح از اسکوپ خودشون میرنکلاس ها توی جاوااسکریپت چیزی نیستن جز تابع، اگه میخوایی بگی اون کلمه class که توی ES6 معرفی شده پس چیه ؟ باید بگم اون فقط یه پوسته اس برای کدنویسی تمیز‌‌‌‌‌‌تر و  پشت قضیه اش همش تابع اس و object بعدن به این موضوع مفصل میپردازیم الان عصبانی شدی میگی آقا یعنی چی هی میگی بالاترین سطح از اسکوپ خودشون ؟؟؟یعنی اگه یک متغیر توی حوزه‌ی سراسری تعریف شده باشه، به بالاترین قسمت کد جابجا میشه و اگه یک متغیر توی اسکوپ لوکال تعریف شده باشه، به اول اسکوپ خودش جابجا میشهعصبانیت نداره که توی مثال زیر میفهمی چی میگم، فرض کن کد زیر رو ما نوشتیمvar name = &#039;Mohammad&#039;;
console.log(name);در واقع جاوا‌اسکریپت پشت قضیه کد بالا رو اینطوریش میکنه(ای آدم زرنگ)var name = undefined;
name = &#039;Mohammad&#039;;
console.log(name);عه چی شد ؟؟؟ اومد name رو برداشت به بالاترین سطح اسکوپ خودش برد و بهش مقدار undefined داددر واقع داره میگه من name رو میبرم اون بالا ولی مقدارش نمیدونم چیه پس بهش undefined میدم تا وقتی رسیدم بهش مقداری که تو دادی رو (یعنی  &#x27;Mohammad&#x27;) جاگذاری میکنم توی name (برنامه نویس: ما داریم اینجا زحمت میکشیم)برای اثبات حرفم یه کنسول لاگ بندازی قبل اون var name = Mohammad میبینی که مقدار undifined رو بهت پس میدهاین چه معنی میده ؟؟؟ به این معنیه که تو قبل اینکه متغیرت initialize بشه مقدار میگیره اونم چی ؟undefined و میتونی بهش دسترسی داشته باشه و این خیلی ممکنه وحشتناک بشه و تولید باگ کنهیه مثال دیگه بزنیم، این‌بار با توابعهمون طور که می‌دونید سه نوع تابع توی جاوا‌اسکریپت داریمfunction declarationfunction expressionarrow functionوقتی یه تابعی از نوع function declaration داریم مثل مثال زیر :showName();
function showName () {
        console.log(name);
}می‌تونیم قبل از تعریف کردنش صداش بزنیم و این به لطف وجود Hoisting هستش کلا علت وجود Hoisting هم دقیقا همینهخب تا اینجا ما همش راجب var و function declaration حرف زدیم و Hoisting رو توی اونا بررسی کردیماما let, const و توابع نوع arrow و expression چطور ؟؟؟اول let, const  رو بررسی کنیم‌:این دوتا عزیز هم Hoisted میشن با این تفاوت که دیگه مقدار undefined نمیگیرن بلکه جاوا‌اسکریپت به ما خطا بر میگردونهاصلا ولش کن، کد زیر رو ببین تا بهت بگم جریان چیه// var Hoisting
console.log(name);
var name = &#039;Mohammad&#039;; 
console.log(name);

// let Hoisting
console.log(name); 
let name = &#039;Mohammad&#039;;  
console.log(name);همون طور که میبینید سه خط کد اول که با var هستن اجرا میشن و مقدار name اول میشه undefined(به خاطر همون hoisting) و مقدار name دوم، بعد از تعریف  var میشه &#x27;Mohammad&#x27;اما توی سه خط کد دوم وقتی جاوااسکریپت به خط اول که میرسه میگه عه عه name رو تعریف کردی ولی مقدار دهیش نکردی؟فکر کردی من مثل var بی دروپیکر هستم ؟ پس ارور زیر رو میده :ReferenceError: Cannot access &#039;name&#039; before initializationدر واقع let, const هم Hoisted میشن ولی دیگه مقدار undefined نمیگیرن و قبل از تعریف قابل دسترس نیستندقت کنید خطا داره میگه name مقدار‌دهی نشده (نشون دهنده اینه که Hoisting داره کار میکنه) نه اینکه تعریف نشده بین دوتا فرق هستnot defined ==! not initializeیه مطلب کوچیک :اگه نمیدونید declaration و assignment و initialize فرقشون چیه کد زیر رو ببینیدlet name;                  =&gt;   declaration (define variable)
name = &#039;Ali&#039;;              =&gt;   initialize
let name = &#039;ali&#039; ;        =&gt;   assignment = declaration + initializeاما توابع arrow  و expression چطور‌ ؟؟؟ خب بستگی داره با چی تعریفشون کنیاگه با var تعریف بشن خب رفتارشون توی بحث Hoisting عین همون var میشه اگه با const, let تعریف بشن هم که دیگه Hoisting اشون طبیعتا شبیه خود let, const هستشخب آخرین مبحثی که بهش میپردازیم Temporal Dead Zone هستشعکس زیر رو ببینTemporal dead zoneبه اون منطقه ای که از اسکوپ متغیر مورد نظر تا مقداردهی کردن اون متغیر هست رو منطقه TDZ میگیمالان کد توی عکس رو ببین، اسکوپ متغیر job میشه بلاک if (علتش؟ تو مقاله قبل گفتمش) و توی خط چهارم بلاک if هم مقداردهی شده اون منطقه از شروع اسکوپش تا مقداردهیش رو که متغیر در دسترس نیست رو میگن منطقه مرگ موقتی یا TDZبازم تکرار میکنم ما ارور initialize گرفتیم یعنی جاوااسکریپت میدونه متغیر تعریف شده (declare) ولی مقداردهی نشده (initialize) و این با ارور دوم که not define هست فرق میکنه یعنی کلا ما متغیری با این اسم تعریف نکردیم (مثل x)امیدوارم بدردتون خورده باشه اگه سوالی چیزی داشتین یا دیدین جایی رو اشتباه گفتم تو نظرات بگید اگه هم دوست داشتین توی کانال تلگرامم عضو بشید LearnByLearn@ممنون</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Fri, 08 Mar 2024 20:25:25 +0330</pubDate>
            </item>
                    <item>
                <title>اندر احوالات جاوااسکریپت (قسمت سوم)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%A7%D9%86%D8%AF%D8%B1-%D8%A7%D8%AD%D9%88%D8%A7%D9%84%D8%A7%D8%AA-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D9%82%D8%B3%D9%85%D8%AA-%D8%B3%D9%88%D9%85-m9hcawsnbtcc</link>
                <description>سلام سلامرسیدم به مبحث جذاب scoping توی زبان شیرین javascript 😎اگه مقاله قبل رو خونده باشید گفتم Execution Context سه تا مورد داره که یکی از اون سه مورد یعنی scope مبحث اصلی این قسمت هستشاسکوپ یعنی اون محدوده ای که variable های ما توی اون تعریف شدن و خارج از اون محدوده قابل دسترسی نیستن.پس وقتی پرسیدن اسکوپ یا محدوده یک متغییر کجاست ؟؟؟ 🤨  باید بگیم محدوده ای از کد ما که اون متغییر بهش دسترسی داره . اوکی؟حالا ما 3️⃣ نوع اسکوپ داریم :1️⃣ اولیش میشه Global Scope :به کجا میگن گلوبال اسکوپ ؟؟؟ هرجایی که خارج از function و block باشه (منظور از بلاک اینه 👈🏻 {}) یعنی بی در و پیکرترین اسکوپ ما همینه چون متغییرهاش رو همه بهش دسترسی دارن2️⃣ دومین اسکوپ ما Function Scope (Local Scope هم بهش میگن) :توی این نوع اسکوپ متغییر ها فقط و فقط در داخل function قابل دسترسی هستنمتغییر هایی که با var خدا بیامرز (دیگه استفادش نکنید ) تعریف میشن جز این دسته اسکوپ هستنتوی مثال بالا متغییر myName فقط توی تابع قابل دسترس هست (vscode هم کم رنگش کرده) و اگه خارج از تابع بخوایی بهش دسترسی پیدا کنی reference error میگیری در واقع میگه من متغییری به اسم myName ندارم، چیزی زدی؟😰3️⃣  آخرین اسکوپ ما Block Scope هستش که توی ES6 معرفی شد :توی این اسکوپ متغییر ها فقط و فقط توی بلاک { } خودشون قابل دسترسی هستن . بلاک مثل چی ؟ مثل if یا for یا switchدقت کنید که let و const هم بلاک اسکوپ هستنتوی حالت strict mode خود function ها هم بلاک اسکوپ هستن، یعنی چی؟🤔 یعنی اگه تابعی رو داخل یه بلاک قرار دادی و strict mode هم روشن کردی نمیتونی خارج اون بلاک بهش دسترسی داشته باشی مثل مثال زیرپس یکی از تفاوت های var با let , const رو زیر پوستی یاد گرفتین، که اون تفاوتم میشه ؟ اسکوپشونتفاوت های دیگشون رو قسمت های بعدی میگم، آسیاب به نوبتنکته بعدی مکانیزمی به اسم scope chain هست یعنی زنجیره اسکوپی، حالا این زنجیره اسکوپی میخواد چی رو برسونه ؟؟؟ بریم با مثال یادش بگیریمتصویر بالارو ببینید فرض کنید میخواییم به اون myName دسترسی پیدا کنیم خب سوال اینجاست که myName که توی اسکوپ تابع second تعریف نشده که پس باید ارور بده دیگهاما نه ✋🏻!!! چون جاوااسکریپت باهوشه، اول توی همون اسکوپ که متغییر myName صدا  زده شده جست و جو میکنه میبینه ای دل غافل چیزی نیست که، میره اسکوپ بالاترش یعنی تابع first رو میگرده میبینه ای بابا اینجام نیستش پس بازم  میره بالاتر (یعنی اسکوپ گلوبال) میبینه خط اول تعریف شده پس مقدار myName رو میزاره jonas پس به کل این فرایند جست و از داخل به بیرون برای دسترسی به یک متغییر رو میگن scope chainدرواقع انقدر به اسکوپ بالاتر میره تا به تهش برسه پیداش کنه، در این بچه پیگیریهچندتا نکته حواست باشه :☝🏻فرایند جست و جو از داخل به بیرونه مثل یه خیابون یک طرفه اس و برعکسش صدق نمیکنه☝🏻جست و جو نسبت به بلاک بالاتر صورت میگیره نه بلاک همسایه یعنی جاوااسکریپت نمیاد برای myName اون بلاک if رو بگرده بلکه بلاک بالاترش که first هست رو میگرده اون باکس بنفش و زرد هم داره این موضوع رو نشون میده☝🏻 دقت کنید برای جست و جو یک اسکوپ جاوااسکریپت به ترتیب محل تعریف اسکوپ ها و بلاک ها نگاه میکنه، کاری نداره که تابع به ترتیب صدا زده شده باشه (برعکس Execution Context مقاله قبل که با صدا زدن تابع کار میکرد) ☝🏻 توی scope chain تمام اسکوپ ها به متغییر های بیرونی خودشون دسترسی دارنامیدوارم به دردتون خورده باشه توی قسمت بعد میریم اون بالا بالا ها تا Hoisting رو یاد بگیریم و طرز کارشو بفهمیمهرجا متوجه نشدین یا من اشتباه گفته بودم کامنت بزاریدموفق باشید ❤️</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Tue, 27 Feb 2024 21:35:21 +0330</pubDate>
            </item>
                    <item>
                <title>اندر احوالات جاوااسکریپت (قسمت دوم)</title>
                <link>https://virgool.io/@MohammadBohluli/%D8%A7%D9%86%D8%AF%D8%B1-%D8%A7%D8%AD%D9%88%D8%A7%D9%84%D8%A7%D8%AA-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-zlijti23omwz</link>
                <description>توی قسمت قبل فهمیدیم که موتور جاوااسکریپت چیه و پس قضیه چطور کار میکنه ، این قسمت می خواییم بیشتر وارد جزئیات call stack  بشیمهمون طور که قسمت قبل گفتم توی call stack مفهومی به اسم EC (Execution Context) داریماین EC چی هست ؟ 🤔 محیطی که کد های جاوااسکریپت توش اجرا میشن یا محل ذخیره اطلاعاتی که کد ما برای اجرا بهش نیاز دارهیه پیتزا کامل رو در نظر بگیرید ، هر تیکه 🍕 از این پیتزا میشه کد جاوااسکریپتی ما و کل پیتزا میشه اون ECحالا این EC  چه موقع ساخته میشه  :اولیش Global EC هست که توی هیچ تابعی نیست و در بالاترین سطح کد (top-level) یعنی جایی خارج از توابع ما ساخته میشه و فقط یک دونه ازش داریمدومین EC ما به ازای هر تابع که صدا زده میشه ساخته میشه ، دقت کنید دارم میگم صدا زده میشه نه اینکه تعریف میشه اون جایی که تعریف کردن تابع مهم میشه برامون میشه scope که توی مقاله بعدی میرم سر وقتشهر EC یه سری اطلاعات توش هست :1. Variable environments (let, const, var, function, …)2. Scope3. This keywordهیچی عین مثال نیست پس کد زیر رو داشته باش:Execution Context· همیشه اول Global EC ساخته میشه و وارد call stack میشه ، همون طور که توی تصویر میبینید جاوااسکریپت اول به name رسیده و خب مقدارش رو قرار داده حالا به first و second رسیده و مقدارشون یه تابع است که هنوز اجرا نشدن و وقتی که به مقدار x می رسه چون تابع first هنوز اجرا نشده مقدارش نامعلومه· حالا میبینه که first اول از همه صدا زده شده (کاری با محل تعریفش نداریم، صدا زدن مهمه برامون) پس میاد یه EC براش میسازه و میاد رو Global EX قرار میگیره (اون جریان پشته رو که از قسمت اول یادتونه؟😉)· وارد تابع first میشه ، مقدار a رو قرار میده اما مقدار b باز نامعلومه، میبینه که second صدا زده شده پس تابع first رو رها میکنه و میره برای second یه EC میسازه· توی second مقدار c که مشخصه حالا میرسه به return و به محض رسیدن به return تابع second از call stack پر میکشه میره بیرون، الان فقط یه first و Global EC  داریم· حالا ادامه تابع first رو میره حالا دیگه مقدار b نامعلوم نیست چون از second مقدارشو گرفته و a+b میکنه و در اخر return میشه و first هم عین second از call stack پر میکشه میره· الان یه  Global EC تک و تنها مونده و مقدار x هم مشخص شده پس Global EC هم میبینه دیگه کاری نداره پر میکشه میره و قصه ما به سر رسید😒امیدوارم به دردتون خورده باشهاگه جایی اشتباه کردم یا مفهوم رو نرسوندم تو نظرات بهم بگید ممنون</description>
                <category>Mohammad Bohluli</category>
                <author>Mohammad Bohluli</author>
                <pubDate>Mon, 19 Feb 2024 15:32:37 +0330</pubDate>
            </item>
            </channel>
</rss>