<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های یاسین سیلاوی</title>
        <link>https://virgool.io/feed/@ysilavi</link>
        <description>برنامه‌نویس، مدرس و یه نویسنده خیلی معمولی :)</description>
        <language>fa</language>
        <pubDate>2026-06-17 00:35:48</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/267418/avatar/B08iJk.png?height=120&amp;width=120</url>
            <title>یاسین سیلاوی</title>
            <link>https://virgool.io/@ysilavi</link>
        </image>

                    <item>
                <title>چرا تیم‌های نرم‌افزاری به مدیر محصول تکنیکال نیاز دارند؟</title>
                <link>https://virgool.io/@ysilavi/%DA%86%D8%B1%D8%A7-%D8%AA%DB%8C%D9%85-%D9%87%D8%A7%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1%DB%8C-%D8%A8%D9%87-%D9%85%D8%AF%DB%8C%D8%B1-%D9%85%D8%AD%D8%B5%D9%88%D9%84-%D8%AA%DA%A9%D9%86%DB%8C%DA%A9%D8%A7%D9%84-%D9%86%DB%8C%D8%A7%D8%B2-%D8%AF%D8%A7%D8%B1%D9%86%D8%AF-gr8h7jgwmksh</link>
                <description>با خوندن این نوشته می‌تونی نقش یه مدیر محصول تکنیکال (Technical Product Manager) توی تیم نرم‌افزاری بفهمی و شرح وظایف اون رو متوجه بشی.مدیر محصول فنی کیه؟مدیر محصول فنی در اصل مترجم نیازهای تیم کسب‌وکار (Business) برای تیم‌های توسعه (Development) و فنیه؛ اگه شما تو این نقش فعالیت می‌کنید باید اول مطمئن بشید که نیاز‌های تیم کسب‌وکار و بعد از اون محصول‌ (Product) رو به صورت کامل درک کردید و می‌تونید تیم توسعه رو برای پیاده‌سازی اون نیازمندی‌ها هم سو و هم ذهن کنید.شما به عنوان یک مدیر محصول فنی باید نیازمندی‌های تیم کسب‌وکار رو به قدم‌هایی شفاف و اقداماتی مشخص برای تیم توسعه تبدیل کنید؛ اما این به معنی جدا شدن شما از چرخه محصول نیست، چون شما هنوز هم مسئول مستقیم اون محصول و موفقیت اون در بازار (Market) هستید.شما مسئول شناسایی نیازمندی‌های کاربر و طراحی راه حل برای اون‌ها هستید. شما با تیم‌های فنی و غیرفنی تعامل مستقیم دارید و همیشه محصول رو تحت نظر (Monitoring) دارید و در صورت نیاز به تکنولوژی‌های جدید، اون‌ها رو برای استفاده در جای مناسب وارد بازی می‌کنید.وظایف شما در یک نگاه:اطمینان از شفافیت نیازمندی‌های تیم کسب‌وکار و محصول برای تیم‌های توسعهتبدیل نیازمندی‌های تیم کسب‌وکار و محصول به مسیرهای واضح و اقدامات قابل پیاده‌سازیبررسی و تلاش مداوم برای ارتقا محصول و سرویس‌های فعلیشناسایی گلوگاه‌های تجربه کاربری و ارائه راه‌حل‌های سریعایجاد هماهنگی کامل بین تیم کسب‌وکار و تیم‌های توسعهایجاد هماهنگی موفق بین تیم‌های فروش و مارکتینگکاهش زمان توسعه و افزایش سرعت ورود به بازارتفاوت مدیر محصول (PM) و مدیر محصول فنی (TPM) چیه؟مدیر محصول معمولا بر نیاز کاربران، ایجاد نقشه راه محصول (Roadmap)، استراتژی تیم، نحوه ورود به بازار و موارد مشابه این تمرکز داره در حالی که مدیر محصول فنی تمرکزش رو بیشتر روی ترجمه نیازمندی‌های تیم کسب‌وکار برای تیم‌های توسعه، هماهنگی با تیم توسعه، جزئیات فنی و معماری، اجرای صحیح نقشه راه محصول (چیزی که مدیر محصول اون رو طراحی کرده) و همینطور کیفیت و تحویل فیچرها میذاره. به صورت خلاصه مدیر محصول میگه چیو بسازیم و چرا اون رو بسازیم ولی مدیر محصول فنی میگه چطوری بسازیمش و با چه کیفیتی!</description>
                <category>یاسین سیلاوی</category>
                <author>یاسین سیلاوی</author>
                <pubDate>Mon, 17 Nov 2025 16:23:24 +0330</pubDate>
            </item>
                    <item>
                <title>باسلام، خداحافظ! ولی این دفعه جدی‌ام!</title>
                <link>https://virgool.io/@ysilavi/%D8%A8%D8%A7%D8%B3%D9%84%D8%A7%D9%85-%D8%AE%D8%AF%D8%A7%D8%AD%D8%A7%D9%81%D8%B8-%D9%88%D9%84%DB%8C-%D8%A7%DB%8C%D9%86-%D8%AF%D9%81%D8%B9%D9%87-%D8%AC%D8%AF%DB%8C-%D8%A7%D9%85-f355weijnq76</link>
                <description>سه سال و نیم در باسلام مثل پلک زدنی گذشت و هنوز هم فکر کردن به جدایی از آن مثل یک رویاست؛ رویایی که هنوز نمیدانم انتهای آن تلخ است یا شیرین. اصلا رویا نه بلکه بیشتر به مسیری می‌ماند که باید آن را طی کرد، چرا که دنیا اینگونه است و ما چه بخواهیم و چه نه زندگی جریان دارد ...تیم دوست داشتنی باسلامو منی که این خزعبلات را طوری به هم بافتم که انگار اونها رو مثل گنجی از بین یادداشت‌های به‌جا مونده یکی از نویسنده‌های متبحر کش رفتم، یاسین سیلاوی هستم؛ یک برنامه‌نویس، مدرس و نویسنده خیلی معمولی که جدیدا قصد کرده از تیم باسلام جدا بشه.و چه موضوعی بهتر از این برای یک خوره نوشتن مثل من؟! من همیشه باسلام رو دوست داشتم و بعد از اون متنفر شدم و بعدتر دوباره عاشقش شدم و الان که دارم از اون جدا میشم حس می‌کنم دارم بهترین شرکت دنیا رو ترک می‌کنم.و البته این من رو می‌ترسونه! ترس از اینکه آیا دوباره شرکتی مثل باسلام و آدم‌هایی مثل هم تیمی‌هام پیدا می‌کنم یا نه. ولی چاره‌ای نیست! وقتی رو به رو تاریکی وایسادی و نمی‌دونی اون تو چخبره تنها راه اینه که واردش بشی و وقتی چشم‌هات عادت کرد می‌تونی جواب سوالت رو بفهمی، و این تنها راهه! راهی که ما انسان‌ها بهش میگیم تجربه.من هم الان رو به رو تاریکی خودم وایسادم و دروغ نمیگم واقعا ترسناکه! اما چه بهتر! این یعنی هیجان بیشتر! یعنی بعد از عبور از اون قراره دنیا رو طوری ببینم که تا الان امکان نداشت ببینم و نهایتا یعنی تجربه بیشتر!و به‌نظرم تجربه تو جوونی از نون شب هم واجب‌تره! تجربه‌ست که انسان رو از خامی درمیاره، تجربه بود که شیخ صنعان رو شیخِ صنعان کرد و تجربه‌ست که آخر سر ما انسان‌ها رو باهاش می‌سنجن.در آخر هم برای شما و خودم دعا می‌کنم هر روزمون پر از تجربه‌های جدید مثبت و رو به جلو باشه و بتونیم با استفاده از اونها دنیا رو حتی یه لحظه و حتی برای یه نفر جای بهتری کنیم.دلنوشته‌ای برای آینده۱۸ آذرماه ۱۴۰۲</description>
                <category>یاسین سیلاوی</category>
                <author>یاسین سیلاوی</author>
                <pubDate>Sat, 09 Dec 2023 22:04:48 +0330</pubDate>
            </item>
                    <item>
                <title>چطوری مثل حرفه‌ای‌ها از BEM استفاده کنیم؟</title>
                <link>https://virgool.io/@ysilavi/%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%D9%85%D8%AB%D9%84-%D8%AD%D8%B1%D9%81%D9%87-%D8%A7%DB%8C-%D9%87%D8%A7-%D8%A7%D8%B2-bem-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-dgrclq1mpxl9</link>
                <description>تا حالا به این فکر کردین چطوری میشه BEM رو به «قابل توسعه ترین» حالت ممکن نوشت؟ من که خیلی بهش فکر کردم و الانم اینجام که کشفیاتم رو باهاتون در میون بذارم!تصویر از Nick Page‌حالا این BEM اصلا چی هست؟بِم (BEM) مخفف سه کلمه بلوک‌ (Block)، عنصر (Element) و اصلاح‌کننده (Modifier) ست. بِم یه سبک استاندارد نوشتن CSS محسوب میشه و تقریبا بعیده اگه دنبال یه راه توسعه پذیر برای نوشتن استایل‌های پروژه‌تون هستین، اسمش رو نشنیده باشین.هرچند ما قرار نیست اینجا راجع‌به اصول بِم صحبت کنیم (هین الان هم کلی مقاله و پست عالی وجود داره تو این زمینه) اما بد نیست اگه قبل از شروع بحث اصلیمون این اصول رو یه بار مرور کنیم.بلوک (Block)هر بلوک یه واحد مستقله که به خودی خود معنا داره و می‌تونه چندین بار استفاده بشه (مثلا: میشه دکمه رو یه بلوک در نظر بگیرید؛ یه دکمه به خودی خود معنا داره و نیازی نیست اون رو به بقیه اجزا صفحه مربوط کنیم تا معنا پیدا کنه)عنصر (Element)دقیقا برعکس بلوک، عنصر معنا خاصی نداره. عنصر می‌تونه بخشی از یه بلوک باشه (مثلا: یه لیست خرید ۵ قلمی رو درنظر بگیرید؛ هر قلم توی اون لیست فقط زمانی معنا پیدا می‌کنه که جزئی از لیست باشه و به خودی خود معنایی نداره)اصلاح‌کننده (Modifier)اصلاح‌کننده‌ها رفتار یه بلوک یا عنصر رو تغییر میدن (مثلا: برای تغییر رنگ دکمه (بلوک) یا هر کدوم از اون اقلام لیست خرید (عنصر) می‌تونیم از اصلاح‌کننده‌ها استفاده کنیم)خوب! همینقدر برای اینکه بتونیم مقاله رو ادامه بدیم کافیه و دیگه الان آماده‌ایم یه مثال واقعی بزنیم و قدم به قدم بهترش کنیم. مثلا این کد رو ببینید:&lt;!-- index.html --&gt;
&lt;button class=&amp;quotbutton button--blue&amp;quot&gt;
    &lt;img src=&amp;quotbasket-icon.svg&amp;quot class=&amp;quotbutton__icon&amp;quot /&gt;
    سفارش بده
&lt;/button&gt;بریم بلوک، عنصر و اصلاح‌کننده‌ها را مشخص کنیم. می‌دونیم که بلوک نباید وابستگی داشته باشه، پس تگ button (که با کلاس button مشخص شده) اینجا بلوک ماست.حالا سراغ تگ img (که با کلاس button__icon مشخص شده) میریم. می‌تونیم فرض کنیم محتوی این تگ آیکون سبد خریده و کنار متن «سفارش بده» نمایش داده میشه؛ از توضیحات میشه فهمید که این آیکون ما به خودی خود با معنی نیست و فقط وقتی معنی داره که توی این دکمه و کنار اون متن نمایش داده بشه؛ پس به همین راحتی عنصر خودمون رو هم پیدا کردیم!آخر سر هم سراغ کلاس button--blue میریم که حتما متوجه شدین یه اصلاح‌کننده‌ست. از قبل می‌دونیم که اصلاح‌کننده‌ها رفتار بلوک یا عنصر رو تغییر میدن؛ و ما هم اینجا از این کلاس استفاده کردیم تا بتونیم رنگ دکمه‌مون رو عوض کنیم.      ‌                  ‌                    ‌   استایلی که میشه برای این دکمه نوشت احتمالا یه چیزی شبیه اینه:/* styles.css */
.button {
    cursor: pointer;
}

.button__icon { 
    font-size: 24px;
}

.button--blue {
    color: white;
    background-color: royalblue;
}دقیقا به محض دیدن این کد میشه فهمید که یه چیزی درست نیست! ما مجبور شدیم کلاس button رو سه مرتبه تکرار کنیم که البته شاید به‌نظر چیز مهمی نباشه؛ ولی وقتی یکمی تعداد استایل‌ها بیشتر بشه تکرار کردن یه عبارت (هرچند به کوچکی button)، پشت سر هم واقعا عذاب آور میشه.ضمنا استایل‌های ما خیلی جدا از هم به‌نظر میرسن و اگه کسی دانش بِم نداشته باشه ممکنه حس کنه سه تا کلاس مختلف برای سه تا کار مختلف ساختیم و اینها اصلا با هم در ارتباط نیستن؛ با اینکه اصلا اینطور نیست و همه‌شون در واقع مربوط به بلوک button ما هستن و نباید جدا از اون استفاده بشن.اما خوب راه حل چیه؟ چطوری میشه هم جلوی تکرار رو گرفت و هم مطمئن بشیم استایل‌های مربوط به یه بلوک با هم یکپارچه شدن؟ جواب یک کلمه‌ست! Sass!حالا Sass چیه و چجوری؟گفتیم میشه با ترکیب کردن BEM و Sass مسائل قبلی رو حل کرد؛ ولی حالا این Sass چی هست اصلا؟ سَس یه پیش پردازنده (pre-processor) برای زبان سی اس اسه. ولی الان خیلی نمیخواد خودمون رو درگیر معنای پیش پردازنده کنیم؛ سَس برای ما همون سی اس اس با یه سری امکانات ویژه‌ست!تورفتگی (Nesting)یکی از امکاناتی که سَس بهمون میده تورفتگیه! سَس بهمون اجازه میده هر چندتا سلکتور رو که دوست داشتیم توی هم قرار بدیم. یه چیزی مثل این:/* styles.scss */
.button {
    cursor: pointer;

    .button__icon {
        font-size: 24px;
    }
} این سلکتورهای داخلی بعد از کامپایل به شکل زیر درمیان:/* styles.css */
.button .button__icon {
    font-size: 24px;
}کاراکتر &#x60;&amp;&#x60;یکی دیگه از امکانات مفید سَس برای ما کاراکتر &amp; هست.  ما میتونیم از &amp; استفاده کنیم تا جلوی تکرار سلکتورها رو بگیریم. مثلا اینجا:/* styles.scss */
.button {
    cursor: pointer;

    &amp;__icon {
        font-size: 24px;
    }
}به‌جای اینکه دوباره button. رو تکرار کنیم از &amp; استفاده کردیم. سَس موقع کامپایل زحمت تکرار کردنشون رو می‌کشه.هووم! مسئله‌هایی که میخواستیم حلشون کنیم رو یادتونه؟ تکرار نه، یکپارچگی آره! و الان دقیقا می‌دونیم چطوری باید این کارها رو انجام بدیم! کد قبلی رو یادتونه؟ وقتشه به نسخه جدیدش سلام کنیم!/* styles.scss */
.button {
    cursor: pointer;

    &amp;__icon {
        font-size: 24px;
    }

    &amp;--blue {
        color: white;
        background-color: royalblue;
    }
}دیگه خبری از تکرار نیست و همین الان هم این کد نسبت به قبل خودش خیلی یکپارچه‌تر شده؛ حتی اگه کسی با بِم هم آشنا نباشه متوجه میشه تمام این سلکتورها یه ارتباطی با هم دارن و نباید جدا از هم دیگه استفاده بشن.خوب! الان دیگه می‌دونیم حرفه‌ای‌ها چطوری بِم و سَس رو با هم ترکیب می‌کنن تا مسائلی که دیدیم رو حل کنن؛ ولی این همش نیست! میشه با انجام یه سری ترفندهای کوچیک توسعه پذیری کدهامون رو از اینی که هست هم بهتر کنیم؛ یا به عبارت دیگه از حرفه‌ای ها هم حرفه‌ای تر کد بزنیم!‌   ‌ترتیب رو رعایت کن!اولین قانون نانوشته‌ای که می‌تونه کدمون رو یکمی بهتر از قبلش کنه ترتیبه! هرچقدر کدی که می‌نویسیم قابل پیش‌بینی‌تر باشه خوانایی اون هم بیشتر میشه. ولی خوب کاربردش برای ما چیه؟ ما به کجای کدمون می‌تونیم ترتیب بدیم؟برای پیدا کردن جواب سوالمون، پیشنهاد می‌کنم دوباره یه نگاهی به استایل‌های بلوک button بندازیم ولی این دفعه جزئی‌تر:/* styles.scss */
.button {
    cursor: pointer;

    &amp;__icon {
        font-size: 24px;
    }

    &amp;--blue {
        color: white;
        background-color: royalblue;
    }
}ترتیبی که اینجا رعایت کردیم اینه: اول از همه بلوک، بعد عناصر (با ترتیبی که توی اچ تی ام ال نوشته شدن) و در آخر هم اصلاح‌کننده‌هاخوبه این ترتیب رو برای همه بلوک‌هامون رعایت کنیم، اینطوری حتی اگه یه بلوک خیلی بزرگ (مثلا ۴۰۰ ۵۰۰ خطی!) هم داشته باشیم راحت می‌دونیم کجا دنبال چی بگردیم.عالی میشه اگه ترتیب عناصر رو همونطوری که توی اچ تی ام ال داریمشون پیاده کنیم؛ یعنی اگه button__icon. اولین عنصری هست که توی اچ تی ام ال اون رو می‌بینیم، توی استایل‌ها هم همینطور باشه.ریسپانسیو، همه با هم!تا اینجا هیچ حرفی از ریسپانسیو نزدیم؛ اما الان داریم از سَس استفاده می‌کنیم و این یعنی هر کجا که دلمون بخواد می‌تونیم media@ بذاریم و اونجا رو ریسپانسیو کنیم؛ یه چیزی مثل این:/* styles.scss */
.button {
    cursor: pointer;

    &amp;__icon {
        font-size: 24px;

        @media (max-width: 1024px) {
            font-size: 20px;        
        }
    }
}و می‌تونیم همین روش رو ادامه بدیم و دونه دونه هر کدوم از عناصرمون رو ریسپانسیو کنیم؛ ولی واقعا مجبوریم دونه دونه به هر کدوم از عناصر media@ بدیم؟ معلومه که نه!هرچند نمیشه گفت این روش اشتباهه، ولی اینکه مجبوریم هر بار media@ رو تکرار کنیم اصلا جالب نیست و دیگه لازم نیست اضافه کنم ما به عنوان برنامه نویس از تکرار بدمون میاد! از بخت خوب، این بار مسئله پیش رومون اصلا پیچیده نیست!برای حلش کافیه همه media@ ها رو یه سطح آورد بالاتر و توی بلوک نوشت. به همین سادگی! اینطوری دیگه خبری از تکرار نیست! ولی جدا از اون، اینطوری ریسپانسیو کردن هم خیلی ساده‌تر میشه (بهم اعتماد کنید دیگه نصف قبل هم ازتون وقت نمی‌گیره!) این مثال رو ببینید:/* styles.scss */
.button {
    cursor: pointer;

    &amp;__icon {
        font-size: 24px;
    }

    &amp;--blue {
         color: white;
         background-color: royalblue;
     }

    @media (max-width: 1024px) {
        &amp;__icon {
             font-size: 20px;
         }

         &amp;--blue {
              border: 1px solid white;
          }
}الان برای اینکه بفهمیم این بلوک صفحه نمایش‌های زیر ۱۰۲۴ پیکسل چطوری رفتار می‌کنه کافیه media@ مربوط به اون اندازه رو ببینیم و تمام! دیگه نیازی نیست هر عنصر رو دونه دونه نگاه کنیم تا بفهمیم چی شده.  ‌  ‌  ‌خوب این هم از این! با دونستن این جزئیات هرچی که لازم بود رو می‌دونیم! و الان دیگه می‌تونیم با خیال راحت بریم پیش اون دوستمون که مشغول کار خودشه، و بهش یادآوری کنیم ما بلدیم مثل حرفه‌ای‌ها کد بِم بزنیم! :)</description>
                <category>یاسین سیلاوی</category>
                <author>یاسین سیلاوی</author>
                <pubDate>Thu, 30 Nov 2023 14:37:25 +0330</pubDate>
            </item>
                    <item>
                <title>تکرارپذیرها و تکرار کننده‌ها در جاوااسکریپت</title>
                <link>https://virgool.io/@ysilavi/%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1-%D8%B4%D9%88%D9%86%D8%AF%D9%87-%D9%87%D8%A7-iterables-%D9%88-%D8%AA%DA%A9%D8%B1%D8%A7%D8%B1-%DA%A9%D9%86%D9%86%D8%AF%D9%87-%D9%87%D8%A7-iterators-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-zwkqirgfdui9</link>
                <description>ما همیشه از نگارش‌هایی مثل Destructuring assignment و Spread توی کدهامون استفاده می‌کنیم؛ اما تا حالا به این فکر کردین که پشت صحنه این نگارش‌ها چطوری کار می‌کنه؟تصویر از Alejandro Barba ‌دقیقا از کدوم نگارش‌ها حرف می‌زنیم؟ممکنه هنوز تردید داشته باشید که با نگارش‌هایی که بالاتر مثال زدم آشنا هستید یا نه. پس بریم یکیشون (مثلا Destructuring assignment) رو در عمل ببینیم! به احتمال زیاد قبلا این کد یا مشابه اون رو دیدین:const [count, setCount] = useState(0);این کد متعلق به کتابخونه ری‌اکته و state داخلی یه کامپوننت رو مشخص می‌کنه. البته خود این کد اینجا اهمیتی نداره و شما می‌تونید اون رو با هر کد مشابه دیگه‌ای جایگزین کنید.‌نکته مهم اینجاست که فانکشن useState یه آرایه به ما برمی‌گردونه؛ و اگه دقت کنید ما برای نام‌گذاری هر کدوم از خونه‌های این آرایه‌مون به جای استفاده از نگارش پایین، از بالایی استفاده می‌کنیم که خیلی تمیزتر و خواناتره.const countStateArray = useState(0)

const count = countStateArray[0]
const setCount = countStateArray[1]‌توی این مثال و نگارش‌های مشابه اون مثل Spread راحت میشه متوجه شد که چه اتفاقی داره می‌افته؛ اما اینکه چطوری این اتفاق می‌افته چیزیه که قراره بزودی اون رو بفهمیم.‌تکرار در برنامه‌نویسیهمیشه وقتی صحبت از تکرار یا Iteration در برنامه‌نویسی میشه یاد حلقه‌ها می‌افتیم. ما در جاوااسکریپت با استفاده از حلقه‌ها می‌تونیم یه عملیات رو بارها و به تعداد نیاز تکرار کنیم؛ مثلا کد زیر رو ببینید:const nums = [1, 2, 3, 4, 5]
const rows = Array(2)

for (let i = 0; i &lt; rows.length; i++) {
  rows[i] = nums[i]
}

console.log(rows) // [1, 2]توی مثال بالا من تعدادی سطر دارم که باید با عدد پر بشن. البته سطرهای من محدود هستن (۲ تا) و همه اعداد توی اون‌ها جا نمیشن؛ برای همین هم من از اول لیست اعداد شروع می‌کنم به برداشتن عدد و فقط اون تعدادی رو برمی‌دارم که بتونم باهاشون سطرهام رو پر کنم.‌هرچند این دقیقا همون کاری که Destructuring assignment برامون انجام میده نیست ولی شاید بشه گفت یه ارتباطی بین Iteration و نگارش‌هایی که تا الان گفتیم وجود داره.‌برای اثبات این ارتباط خوبه که اول یکمی توی Iteration عمیق‌تر بشیم. و با هم چنتا مثال دیگه از Iteration توی جاوااسکریپت رو بررسی کنیم.‌بررسی پشت صحنه حلقه for...ofنگارش for...of بهمون کمک می‌کنه توی حلقه بدون نوشتن کدهای اضافه (boilerplate) به تمام مقادیر آرایه دسترسی داشته باشیم. به این مثال نگاه کنید:const nums = [0, 5, 1]

for (const num of nums) {
  console.log(num)
}توی این مثال اعداد ۰، ۵ و ۱ به ترتیب توی کنسول چاپ میشن. اگه این مثال رو با حلقه for مثال قبل مقایسه کنید می‌بینید که این نگارش خیلی خواناتره؛ که البته این بهترین قسمتش نیست!‌بهترین قسمتش اینه که ما لازم نیست حواسمون باشه که تعداد حلقه بیشتر از طول آرایه نشه یا اینکه مقداری که توی اون حلقه از آرایه باید بگیریم رو به شکل Imperative بنویسیم (مثلا [i]nums)؛ همه این موارد به صورت خودکار توی for...of هندل میشه؛ اما چطوری؟‌یادتونه گفتیم یه شباهتی بین for و تمام نگارش‌هایی که قبلا راجع‌بهشون صحبت کردیم وجود داره؟ خوب این شباهت توی for...of بیشتر هم هست؛ بخاطر اینکه توی دلش داره از Iteration protocols استفاده می‌کنه؛ که جادو پشت صحنه بقیه نگارش‌هایی که راجع‌بهشون صحبت کردیم هم هست!‌پروتکل‌های تکرارپروتکل‌های تکرار در اصل برای استاندارد کردن Iteration در جاوااسکریپت معرفی شدن. ما اینجا با ۲ تاشون کار داریم که حتما اسمشون رو از عنوان حدس زدید: تکرارپذیرها (Iterables) و تکرار کننده‌ها (Iterators)‌پروتکل تکرارپذیرهااین پروتکل به تمام تکرارپذیرها اجازه تکرار شدن رو میده! به زبون ساده‌تر تمام آبجکت‌ها و آرایه‌هایی که ازشون توی حلقه‌ها استفاده می‌کنیم از یه پروتکلی پیروی می‌کنن که رفتارشون رو کنترل می‌کنه.‌هر کدوم از تکرارپذیرها یه متدiterator@@توی خودشون (یا توی پروتوتایپشون) دارن که همونطور که گفتیم مسئول کنترول رفتارشون در Iteration هاست. شما می‌تونید با استفاده از کلید[Symbol.iterator]به این متد دسترسی داشته باشید یا اگه دوست دارید اون رو با متد دلخواه خودتون جایگزین کنید.‌اگه حال ندارید اینکارو انجام بدید ولی مشتاقید ببینید چی میشه؛ جلوتر خودم یه مثال زدم براتون! :))‌پروتکل تکرار کننده‌هاپروتکل تکرار کننده‌ها (Iterators) روش استاندارد تولید دنباله‌ای از مقادیره! جاوااسکریپت به هر آبجکتی که یدونه متدnextتوی خودش داشته باشه میگه تکرار کننده؛ البته به شرط اینکه اون متد یه سری اصول رو رعایت کنه.‌متد next حتما باید یه آبجکت برگردونهآبجکتی که از متد next برمیگرده می‌تونه شامل کلیدهای value و done باشه‌الان دیگه همه دانش لازم برای نتیجه گیری نهایی (اینکه نگارش‌هایی که راجع‌بهشون صحبت کردیم و به اینجا رسیدیم، چطور کار می‌کنن) رو میدونیم؛ اما بیایید قبل از اون، بریم و چیزای جدیدی که یاد گرفتیم رو تو عمل هم ببینیمشون!‌ایجاد رفتار دلخواه در پروتکل‌های تکرارهمونطور که گفتیم تمام تکرارپذیرها یه متدiterator@@دارن که توی[Symbol.iterator]ذخیره شده، و می‌دونیم که آرایه‌ها یکی از تکرارپذیرهای داخلی جاوااسکریپت هستن؛ تیکه کد زیر رو ببینید:const nums = [3, 1, 3]
console.log(nums[Symbol.iterator]()) // Array Iteratorالان تونستیم با استفاده از کد بالا به متدiterator@@این آرایه دسترسی داشته باشیم و اونو صدا بزنیم. اینجا جهان جاوااسکریپته و توی این جهان وقتی می‌تونیم به چیزی دسترسی داشته باشیم یعنی می‌تونیم تغییرش هم بدیم!‌‌من این تیکه کد پایین رو نوشتم که باعث میشه هر دفعه موقع Iterate روی این آرایه تمام اعداد اون به صورت تصادفی جا به جا میشن! شما هم می‌تونید اینکارو انجام بدید و بقیه رو ساعت‌ها درگیر دیباگ کدهای خودتون کنید :))const nums = [1, 2, 3, 4, 5];
nums[Symbol.iterator] = function () {
  let array = this.sort((a, b) =&gt; Math.random() - 0.5)
  let index = 0

  return {
    next() {
      return { value: array[index++], done: array.length &lt; index };
    },
  };
};

console.log(...nums); // 2, 1, 4, 3, 5
console.log(...nums); // 4, 5, 1, 3, 2‌الان دیگه به اندازه کافی می‌دونیم! راجع‌به پروتکل‌های تکرار صحبت کردیم و همچنین دیدیم که چطوری میشه رفتار پیش فرض‌ اون‌ها رو تغییر داد. با توجه به گفته‌های قبلی الان دیگه وقتشه سوال اصلی رو جواب بدیم!‌نگارش‌هایی بر مبنا پروتکل‌های تکرار‌یادتونه تو بخش تکرار کننده‌ها گفتیم برای اینکه یه تکرار کننده بسازیم کافیه یه آبجکت با متدnextداشته باشیم؟ و توی مثال چند خط پیش دیدیم که این متدnextهر بار که صدا زده میشه مقدار فعلی و شرط تموم شدن Iteration رو به ما میده.‌‌این ۲ تا مقداری که متدnextبه ما برمی‌گردونه، تمام چیزیه که نگارش‌هایی که راجع‌بهشون صحبت کردیم (مثل Destructuring assignment و Spread و حتی for...of) بهش نیاز دارن تا درست کار کنن.‌این نگارش‌ها با استفاده از روشی که قبلا گفتیم (کلیدSymbol.iterator) به متدiterator@@اون تکرارپذیر (مثلا آرایه) دسترسی پیدا میکنن و انقدر متد اونnextرو صدا می‌زنن تا مقداری که به عنوان done برمی‌گردونه true بشه!‌‌‌           و بالاخره جواب سوالمون رو پیدا کردیم! فهمیدیم که نگارش‌های اول مقاله چطوری کار می‌کنن و کنار اون یه مقداری هم توی Iteration جاوااسکریپت عمیق‌تر شدیم. پیشنهاد میدم بعد از این مقاله مستندات پروتکل‌های تکرار رو هم حتما یه نگاهی بندازید.</description>
                <category>یاسین سیلاوی</category>
                <author>یاسین سیلاوی</author>
                <pubDate>Sat, 17 Jun 2023 19:04:06 +0330</pubDate>
            </item>
                    <item>
                <title>اولین کد ریویو رسمی من!</title>
                <link>https://virgool.io/@ysilavi/%D8%A7%D9%88%D9%84%DB%8C%D9%86-%DA%A9%D8%AF-%D8%B1%DB%8C%D9%88%DB%8C%D9%88-%D8%B1%D8%B3%D9%85%DB%8C-%D9%85%D9%86-tefnqrqtdfyo</link>
                <description>امروز عصر بعد از اینکه جلسه چَپتِر فرانت رو نِصفه نیمه شرکت کردم یکی از بچه‌ها تماس گرفت و من رو به اولین کد ریویو رسمی عمرم دعوت کرد! یکمی صحبت کردیم و بهم گفت که لینک مرج ریکوئستی رو که من باید بررسی کنم رو برام فرستاده؛‌ ‌خوب! مثل هر آدم کنجکاو دیگه‌ای منم فاصله بین گوشی و کامپیوتر رو پرواز کردم که ببینم این کدی که قراره ریویو کنم چطوریه و اصلا مربوط به کجای پروژه است؛ خوب اگه شما هم مشتاقید باید بگم کد مقصود مربوط به یکی از بخش‌هایی بود که قبلا روش کار کرده بودم ( اگه فکر می‌کنید خوب مسلمه! قطعا توی باسلام کار نمی‌کنید! )‌ ‌‌ ‌حالا چرا همه اینا رو گفتم؟ چون کد رو نگاه کردم و به یه سری مسئله‌های خیلی ساده برخوردم که اگه بهشون دقت کنیم احتمالا در طولانی مدت کد بهتری داشته باشیم! ( و خوب این دلیل خوبی شد برای کنار گذاشتن تنبلی و نوشتن یه پست جدید که واقعا به درد یکی بوخوره! )‌ ‌اولین قانون نانوشته : قبل از نوشتن، فرمت کنید!فرمت نبودن کدها اولین چیزی بود که توی این کد ریویو به چشمم خورد، و فهمیدم که اگر با کسی که داره کد شما رو ریویو می‌کنی دشمنی دارید کافیه کدتون رو فرمت نکنید! صد در صد تضمین می‌کنم که طرف حتما سردرد می‌گیره!‌ ‌ولی جدا همخوانی نداشتم indent ها توی فایل‌های مختلف ( یا حتی بدتر! توی خط‌های مختلف یه فایل ) واقعا باعث میشه خوندن اون کد برای همه حتی خودمون سخت بشه، و توی طولانی مدت هم براتون مشکلات زیادی میاره‌ ‌برای مثال؛یادمه چند وقت پیش یکی از بچه‌ها رو دیدم که یکی دو روز درگیر این بود که چرا استایل‌هایی که به فلان تگ میده اصلا درست کار نمی‌کنن در حالی که همه چیز رو مو به مو از روی یه آموزش پیش رفته بود؛ البته با این تفاوت که کد رو فرمت نکرده بود و به‌زور داشت تلاش می‌کرد بین اون بازار شام مشکل رو پیدا کنه! که احتمالا اگه prettier مثل یه فرشته نجات نرسیده بود و کدش رو فرمت نکرده بود، یکی دو روز دیگه هم باید تلاش می‌کرد تا متوجه بشه یکی از تگ‌ها رو اصلا نَبَسته!‌ ‌البته بعضی‌ها هم عمدا کد رو فرمت نمی‌کنن چون می‌دونن که باعث میشه تغییراتی که بقیه دادن ( ولی یادشون رفته فرمت کنن‌ ) با تغییرات خودشون توی یه کامیت قرار بگیره؛ و خوب اصلا کار درستی نیست شاید حلال حروم بشه!‌ ‌البته جواب این شبهه خیلی سادس! که توی عنوان هم بهش اشاره کردم! قبل از زدن حتی یک خط کد، کل فایل رو فرمت کنید و توی یه کامیت جدا اون رو برای همیشه ثبت کنید!‌ ‌همچنین اگه برای نوشتن کامیت‌هاتون از استاندارد خاصی استفاده می‌کنید احتمالا توی اون استاندارد برای فرمت کردن کد یه مثالی زده شده مثل اینجا که خط پایین رو مثال زده:style (formatting, missing semi colons, etc; no production code change)دومین قانون : به استانداردهای زبان/فریم‌ورکی که باهاش کار می‌کنید احترام بذارید!این مورد هم یکی از چیزهایی بود که قبلا خودم باهاش کاری نداشتم و خلاصه انقدر دردسر درست کردم برای بقیه که هنوز جای مشت و لگدهاشون درد می‌کنه! ( ولی عوضش الان دیگه کاملا رعایت میکنم! )‌ ‌این موضوع خیلی نیازی به توضیح نداره، هرچند که از نظر اهمیت میشه گفت خییییییلیییییی مهمه! حالا چرا؟ چون این موضوع حتی بیشتر از قانون اول کد رو خوانا می‌کنه، حتی می‌تونم بگم اگر استاندارد، درست انتخاب بشه قطعا کمک می‌کنه با درد کم‌تر و سرعت بیشتری فیچر جدید اضافه کنید و خیلی چیزای دیگه که اگه بگم خوندن این مقاله رو ول می‌کنید و میرید سراغ انتخاب استاندارد درست برای پروژه‌تون!‌ ‌فوت کوزه‌گری هم یه سرچ ساده راجب Style Guide اون زبان یا فریم‌ورکی هست که دارید باهاش کار می‌کنید.‌ ‌البته یادتون باشه سخت نگیرید و توی دنیای استاندارد‌های مختلف غرق نشید! چون هرچقدر هم بگردید هیچ وقت به بهترین نمی‌رسید.‌ ‌سومین قانون : فقط تقلید نکنید، یادش بگیرید!یکی دیگه از مواردی که شاید خیلی‌هامون دچارش هستیم همینه! یه سینتکس ناآشنا رو می‌بینیم و از بقیه نمونه‌های توی پروژه استفاده می‌کنیم تا کارمون رو راه بندازیم. ( البته این حرکت معمولا درست جواب می‌ده و عملا هیچ اتفاق اشتباهی نمی‌افته! اما خوب، همیشه این اتفاق نمی‌افته‌ )‌ ‌توی یکی از بخش‌ها متوجه شدم که برای نوشتن استایل‌ها از BEM استفاده شده که به‌نظرم خیلی خوب بود و اون بخش از کد واقعا خوانا بود؛ اما یکمی که دقت کردم دیدم توی ادامه اون بخش بچه‌ها ( از جلمه خودم :D ) اومدن سینتکس رو از روی کدهای قبلی کپی کردن، ( مثل هر برنامه‌نویس حرفه‌ای دیگه‌ای! ) اما متاسفانه مفموم BEM رو رعایت نکردن!‌ ‌مثلا اینجا رو ببینید؛.spinner {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    
    ....
}

.spinner--tiny {
    width: 1.5rem;
    height: 1.5rem;

    ....
}
‌ ‌اگه یکمی راجب BEM خونده باشید این کد کاملا براتون عادیه البته به‌جز یه بخشش! اون قسمت که یه modifier داره دوتا از property های block رو تغییر می‌ده. ( البته می‌دونیم که این اجازه توی BEM وجود نداره بلکه کد رو میشه به شکل زیر نوشت که به‌نظر من بهتره )‌ ‌.spinner {
    border-radius: 50%;

    ....
}

.spinner--normal {
    width: 3rem;
    height: 3rem;
      
    ....
}

.spinner--tiny {
    width: 1.5rem;
    height: 1.5rem;

    ....
}
‌ ‌‌ ‌الان توی این شرایط هیچ کدوم از پراپرتی‌ها override نمی‌شن که کد رو خیلی امن‌تر می‌کنه مخصوصا اگر این دو تا کلاس توی دو تا فایل مختلف باشن که ممکنه یکیشون دیرتر لود بشه!‌ ‌گاها پیش میاد که استایلی که توی لوکال روش کار ‌می‌کنیم کاملا با استایلی که روی سایت اصلی میره فرق داره! و دلیلش هم می‌تونه این باشه که اولویت قرار گرفتن استایل‌ها توی لوکال و سایت اصلی ممکنه فرق داشته باشه ( بخاطر سرعت اینترنت یا نحوه باندل کردن فایل‌ها و ... )‌‌ ‌ ‌‌ ‌خوب به‌نظرم بسه، بقیه موارد رو خودتون اوستا هستید! اگه چیزی رو اشتباه گفتم یا حس می‌کنید ناقصه یا هرچیز دیگه‌ای لطفا بهم اطلاع بدید. ممنون! راستی روزتون هم ( با یکمی تاخیر ) مبارک!</description>
                <category>یاسین سیلاوی</category>
                <author>یاسین سیلاوی</author>
                <pubDate>Tue, 14 Sep 2021 23:09:04 +0430</pubDate>
            </item>
            </channel>
</rss>