<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های علی خاکبازان</title>
        <link>https://virgool.io/feed/@khakbazan</link>
        <description>فرانت اند کاری قلمش بی تابی میکنه برای نوشتن :)</description>
        <language>fa</language>
        <pubDate>2026-06-16 14:09:06</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/3146544/avatar/RGJyGU.jpg?height=120&amp;width=120</url>
            <title>علی خاکبازان</title>
            <link>https://virgool.io/@khakbazan</link>
        </image>

                    <item>
                <title>نسخه جدید NextJS منتشر شد - در NextJS 14.2 چخبره ؟</title>
                <link>https://virgool.io/vaspar/new-nextjs-14-2-mo6glqltgs1z</link>
                <description>نسخه جدید NextJS یعنی NextJS 14.2 منتشر شد و در این نسخه ما شاهد عملکردی بهتر در Development, Production و Cache خواهیم داشت.Turbopack: پاس شدن 99.8% تست ها برای next dev --turboBuild و Production: بهینه تر شدن Build و Production با کاهش مصرف مموری در Build و همچنین بهینه سازی بیشتر فایل های CSSبهبود عملکرد Cache: امکان تنظیم زمان از بین رفتن اعتبار داده های cache شده با staleTimesبهبود Error ها: عملکرد بهتر در مواردی که منجر به Hydration Error میشدن.همچنین اگر علاقه مند به یادگیری مدرن و اصولی فرانت اند از جمله NextJS هستید، پیشنهاد میکنیم نگاهی هم به دوره آموزش فرانت اند ما بندازید.Turbopack برای Developmentطبق گفته داکیومنت نکست، توسعه دهنده های این فریمورک چند ماه اخیر را  مشغول کار برروی ارتقا عملکرد و سرعت Turbopack بودن و حالا در نکست 14.2  بطور کامل و رسمی کارش تمام شده و میتونیم ازش نهایت استفاده رو بکنیم!99.8% تست های نوشته شده Turbopack با موفقیت پاس شدن.300 پکیج برتر npm که بیشترین استفاده رو بین کاربران داشته هم بطور کامل و درست در Turbopack کار خواهند کرد.Lighting CSS هم جهت بهبود عملکرد و بهینه تر شدن CSS افزوده شد.همچنین تیم توسعه دهنده از Turbopack برروی اپلیکیشن های اصلی خودش مثل  vercel.com استفاده کرد تا مطمئن بشه که turbopack در بهترین و پایدار ترین  حالت ممکن خودش هست و پس از استفاده هم نتایج زیر را بدست آورد:تا 76.7% سریعتر در بارگذاری اولیه local serverبروزرسانی کدها تا 96.3% سریعتر با fast refreshتا 45.8% سریعتر در کامپایل اولیه و بدون کش route ها ( Turbopack در حال حاضر Disk Caching نداره )next dev --turboهمچنین اهداف بعدی تیم توسعه دهنده nextjs طبق گفته وبسایت رسمیشون،  برروی بهبود مصرف Memory، پیاده سازی یک حافظه cache دائمی و کار برروی next build --turbo خواهد بود.میزان مصرف Memory: تیم توسعه دهنده ابزارهایی را  ساخته که هم به ما اجازه میده تا عملکرد و میزان مصرف Memory خودمون را  ببینیم و هم به تیم توسعه دهنده اجازه میده لاگ هایی از Performance و مصرف  Memory اپلیکیشن های نکست جی اسی ما ببینه ( البته بدون نیاز به دسترسی به  سورس کد ما )حافظه Cache: همچنین تیم توسعه دهنده بدنبال پیدا  کردن بهترین معماری و راه حل برای پیاده کردن یک حافظه cache دائمی هست و  طبق گفته خودشون به محض دستیابی به اطلاعات بیشتر مارو هم در جریان خواهند  گذاشت.Next Build: تیم توسعه دهنده قصد داره تا build را در حالت Turbopack هم اضافه کنه. در حال حاضر بیش از 76% از تست های  این پیاده سازی پاس شده و به محض تکمیل شدن در اختیار ما قرار خواهند گرفت.بهبود و بهینه تر شدن build و productionعلاوه بر بهبودهای عملکردی که در Turbopack شاهدش بودیم، تیم سازنده  برای build و حالت production هم اقداماتی را داشته ( هم برای pages router  و هم app router )Tree-shakingدر نکست 14.2 تا حد خیلی زیادی دیگه export های بلا استفاده در bundle  ما قرار نخواهند گرفت.به عنوان مثال اگر یک پکیجی نصب کرده باشید که شامل  1000 آیکون مختلفه و شما از یدونه این آیکون ها در یکی از کامپوننت هاتون  صرفا استفاده کرده اید و در این شرایط طبیعتا نمیخواهید که ما بقی اون 999  آیکون هم در bundle شما قرار بگیره و پروژه شمارو سنگین تر بکنه. قبل تر  این اتفاق ممکن بود بیوفته اما حالا در ورژن جدید nextjs شاهد این اتفاق  نخواهیم بود و export های بلا استفاده از bundle ما حذف خواهند شد.این بهینه سازی را برروی پکیجی مثل react-aria-components تست کردند و نتیجه تست هم کاهش 51.3 درصدی سایز بوده.نکته: این بهینه سازی در حال حاضر برای barrel files  کار نمیکنه ( منظور از barrel files کامپوننت هایین که یکجا اونهارو export  کردیم و بعد مجدد توی یک فایل دیگه با یک نام دیگه هم export مجدد ازشون  گرفتیم ) و برای اعمال این بهینه سازی برروی این تیپ پکیج ها در حال حاضر  نیازه تا کانفیگ زیر را در next.config.ts بنویسیم.module.exports = {
  experimental: {
    optimizePackageImports: [&#039;package-name&#039;],
  },
};مصرف Memory در زمان Buildتیم توسعه دهنده NextJS متوجه مصرف بیش از حد Memory در زمان Build  گرفتن شد و پس از بررسی گزارش های کاربران و تست هایی که خودشون انجام دادن  متوجه شدند که دلیل این مصرف بیش از حد memory بخاطر ایجاد فایل های  تکراری جاوااسکریپتی حین build هست و در نتیجه با refactor کردن منطق  bundle و کمی بهینه سازی بیشتر تونستن این مشکل را رفع کنند.در نهایت هم پس از این تغییرات و بهینه سازی ها، نتایج تست نشان دهنده  کاهش سایز و مصرف memory از 2.2GB به زیر 190M بود ( بطور میانگین البته )همچنین بوسیله --experimental-debug-memory-usage که یک  flag در زمان build هست میتونیم بهتر مصرف memory در زمان build را دیباگ  کنیم. برای مطالعه بیشتر هم درباره این مورد میتونید به صفحه بهینه سازی مصرف memory که در وبسایت رسمی nextjs هست مراجعه کنید.بهینه تر شدن نحوه بارگذاری CSS هاتیم توسعه دهنده نحوه بهینه سازی فایل های CSS در زمان Build را تغییر  داده و با با تبدیل فایل های css به فایل های کوچکتر ( css chunks ) مطمئن  میشه که هیچ تداخلی بین استایل های ما در هنگام جابجایی بین صفحات مختلف  پیش نیاد.از nextjs 14.2 به بعد ترتیب css chunk ها بر اساس ترتیب import اونها هستش، به عنوان مثال base-button.module.css قبل از page.module.css قرار میگیرد.// base-button.tsx
import styles from &#039;./base-button.module.css&#039;;
 
export function BaseButton() {
  return &lt;button className={styles.primary} /&gt;;
}// page.tsx
import { BaseButton } from &#039;./base-button&#039;;
import styles from &#039;./page.module.css&#039;;
 
export function Page() {
  return &lt;BaseButton className={styles.primary} /&gt;;
}همچنین برای پیاده سازی درست و با ترتیب اصولی، تیم توسعه دهنده پیشنهاد میکنه که به شکل زیر عمل کنیم:سعی کنید از بجای Global Styles از CSS Modules استفاده کنید.هر CSS Module را منحصر به یک فایل TS/JSدر نظر بگیرید و سعی کنید یک ماژول را در 2 فایل ایمپورت نکنید.اگر از یک className که global تعریف شده استفاده میکنید، اون فایل global را در همان فایل هم ایمپورت کنید.تیم توسعه دهنده میگه که انتظار میره که این تغییرات برروی عملکرد عادی  اپلیکیشن ها تاثیر نزاره، اما اگر دیدید جایی اتفاق غیر منتظره ای افتاد،  حتما نگاهی به ترتیب اصولی پیاده سازی css که در داکیومنت رسمی نوشته شده بندازید.بهبود عملکرد Cacheامروزه مبحث cache یکی از مهم ترین مفاهیم برای داشتن یک اپلیکیشن سریع و  قابل اعتماده و ضرورت وجودش در همه اپلیکیشن های تحت وب حس میشه. عمکرد  cache در اپلیکیشن ها هم باید کاملا اصولی و قابل اعتماد باشه تا به عنوان  مثال زمانی که یک mutation اتفاق میوفته و مثلا یک مقاله جدید به وبلاگ  سایت شما اضافه میشه انتظار میره که این حافظه cache بروزرسانی بشه و آخرین  و تازه ترین داده هارو به کاربران نمایش بده.staleTimesRouter cache سمت کاربر، کاربردش اینه که با cache کردن صفحات دیده شده  یا prefetch شده، تجربه ای سریع و بهینه را به کاربر بده و در این نسخه از  نکست طبق درخواست مکرر کاربران از تیم توسعه دهنده، قابلیتی به نام staleTime اضافه شده که به ما این اجازرو میده تا در client-side router cache یک  بازه زمانی را جهت باطل شدن حافظه cache و تازه سازی اون ثبت کنیم.بطور پیشفرض صفحاتی که از طریق کامپوننت Link و بدون تعیین کردن پراپ prefetch بهشون لینک دادیم، بمدت 30 ثانیه cache میشن و اگر هم prefetch را تعیین و اونرو مساوی true قرار بدیم هم بمدت 5 دقیقه cache میشن.این مقدارهای پیشفرض هم اکنون در این نسخه جدید nextjs قابل تنظیمن و  میتونیم این مدت زمان هارا با قرار دادن کانفیگ زیر در فایل next.config.ts  تغییر بدیم.const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
      static: 180,
    },
  },
};
 
module.exports = nextConfig;هدف از staleTime اینه که کنترلی بیشتر از گذشته برروی مدت  زمان موندگاری cache بده، اما همچنان یک راه حل کامل نیست و تیم توسعه  دهنده میگه که در نسخه های بعدی آزادی عمل بیشتری را در اختیار ما خواهد  گذاشت.Parallel و Intercepting Routesهمچنین برای Parallel Routes و Intercepting Routes هم در این نسخه  بهبود هایی را داریم و این ۲ هم اکنون با Client-side Router Cache سازگار  شدند.بهبود Error هاتیم توسعه دهنده در نسخه 14.1 شروع به کار برروی بهبود ارور ها کرد و  این کار تا به امروز و در نسخه 14.2 ادامه داشت و در نتیجه ما در این نسخه  ارورهایی واضح تر و پر جزئیات تر، با طراحی ظاهری بهتری را میبینیم.این بهبود هم برای App Router و هم Pages Router پیاده شده و در ظاهری  بهتر، هم در نسخه dark و هم light ارورها و لاگ های بهتری را در اختیار ما  قرار میده. در زیر میتونید مثالی از قبل و بعد از این تغییر را مشاهده  کنید.قبل:بعد:React 19پس از اینکه تیم توسعه دهنده ری اکت خبر از نسخه ای جدید یعنی ری اکت 19 را داد، تیم توسعه دهنده NextJS هم دست به کار شد و سعی کردند این قابلیت  های جدید ری اکت که در حال حاضر در نسخه React Canary موجوده را داخل  NextJS هم اضافه کنند و این فرایند همچنان ادامه داره تا زمانیکه تیم توسعه  دهنده NextJS یک نسخه اصلی و هماهنگ با نسخه جدید ری اکت را منتشر کنند.منبع: https://vaspar.io/blog/nextjs-14-2</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Mon, 15 Apr 2024 18:23:27 +0330</pubDate>
            </item>
                    <item>
                <title>بررسی تغییرات ReactJS 19 - در نسخه جدید ری اکت چخبره ؟</title>
                <link>https://virgool.io/vaspar/react19-update-ruq4afytddmz</link>
                <description>تو ReactJS 19 ری اکت 19 چیا داریم ؟ چه تغییرات و اتفاقات جدیدی در این نسخه از React وجود داره ؟ ری اکت یکی  از محبوب ترین لایبرری های دنیای فرانت اند هست و یکی از مهم ترین دلایلی  که خود من به شخصه عاشق این لایبرری هستم، جامعه بزرگ برنامه نویس هاش و  تیمی هست که پشت این لایبرری دوست داشتنی قرار داره.وقتی جامعه برنامه نویس های ری اکت نیازی را حس میکنند و درخواستی را به  سمت تیم سازنده ارسال میکنند، تیم سازنده به خوبی اونهارو میبینه و درصورت  لزوم هم دست به کار میشه.اتفاقات جدیدی که قرار در ری اکت 19 بیوفته واقعا جذاب و دوست داشتنین و  اگر در یک جمله بخوام این بروزرسانی را توصیف کنم باید بگم &quot; کد کمتر،  قدرت بیشتر &quot;.در این مقاله هم قراره بطور کامل نسخه جدید ری اکت یعنی ReactJS 19 را  باهم برسی کنیم و ببینیم چه تغییرات و ویژگی های جدیدی را در این ورژن  خواهیم داشت. توجه داشته باشید که این ورژن هنوز بطور رسمی منتشر نشده و ما  این مقاله را طبق آخرین اطلاعیه ها و اخبار موجود نوشتیم، بنابر این گوش  به زنگ آخرین آپدیت های دنیای وب باشید تا به محض انتشار رسمی، بطور کامل  تر و دقیق تر با ری اکت 19 آشنا بشید.بررسی امکانات جدید در ری اکت 19خیلی سریع و خلاصه بریم اول یک نگاهی به همه چیزهای جدیدی که قراره تو  این ورژن داشته باشیم بندازیم و بعد هم بریم سراغ بررسی تک تک اونها:React compiler: تیم ری اکت هم اکنون داره برروی  کامپایلر جدید خودش کار میکنه و قراره اونرو در ری اکت 19 داشته باشیم. هم  اکنون اپلیکیشن اینستاگرام داره از این کامپایلر جدید استفاده میکنه.Server components: بالاخره بعد از سالها توسعه، ری  اکت سرور کامپوننت هارو معرفی کرد و در react 19 قراره اونرو داشته باشیم.  لازم به ذکر که هم اکنون در nextjs و نسخه canary ری اکت سرور کامپوننت  هارو داریم.Actions: اکشن ها تحولی بزرگ ایجاد میکنند و باعث میشن قدرتمند تر با DOM Element ها تعامل داشته باشیم.Document Metadata: یک قابلیت دیگه که جای خالیش بشدت حس میشد، امکان نوشتن meta data های دلخواه ما بدون هیچ کد اضافی بود.Assets Loading: این قابلیت به ما اجازه میده تا  asset هامونو در background بارگذاری کنیم و در نتیجه سرعت و عملکرد و  تجربه کاربری بشدت ارتقا داده میشه.Web components: این هم یکی دیگه از قابلیت های جدید و  هیجان انگیز در ری اکت 19 هست. از این به بعد میتونیم وب کامپوننت هارو  داخل خود ری اکت بگنجانیم.Hooks: تعدادی هوک جدید هم قراره تو ReactJS 19 داشته باشیم که در ادامه بطور کامل معرفیشون کردیم.ری اکت 19 قراره با یکی از فرسایشی ترین چالش های خودش، یعنی re-render  های اضافی دست و پنجه نرم کنه. مشکلی که سالها برنامه نویس های زیادی  درگیرش بودن و به بهانه های مختلف بهش اشاره میکردن.توسعه دهنده ها معمولا از تکنیک هایی مثل memo, useCallback, useMemo و ... جهت کاهش تعداد این re-render های اضافی استفاده میکردند و در این  ورژن دیگه نیازی به این کارها نیست و خود ری اکت در پشت صحنه این کار هارو  برای ما انجام میده.1.  React Compilerدر حال حاضر، ری اکت بطور خودکار re-render هایی که بخاطر تغییرات state  ها بوجود میان رو مدیریت و بهینه سازی نمیکنه و ما برای انجام اینکار نیاز  داریم تا بصورت دستی و بوسیله چیزهایی مثل useMemo, useCallback و memo  این re-render های اضافی را مدیریت کنیم.اما بازخورد هایی که از طرف جامعه برنامه نویسانی که از ری اکت استفاده  میکنند اومد، تیم ری اکت را وادار کرد تا چاره ای بی اندیشن و کاری کنند که  تمامی این موارد و بهینه سازی ها در پشت صحنه و توسط خود ری اکت انجام بشه  و در نتیجه، تصمیم بر ساخت کامپایلری جدید گرفته شد. این کامپایلر جدید  تصمیم میگیره که کی state را عوض کنه و چه زمانی هم UI را آپدیت کنه.در نتیجه دیگه نیازی نیست ما به عنوان توسعه دهنده زیاد نگران مدیریت  re-render های اضافی باشیم و این بدان معنا هم هست که دیگه نیازی به  استفاده از useMemo, useCallback نخواهیم داشت.یک چیز جذابی هم که درباره ری اکت و تیم توسعه دهنده اون وجود داره اینه  که همیشه آپدیت های جدید، ابتدا برروی پروژه های واقعیشون مثل اپلیکیشن  اینستاگرام تست میشه و بعد بصورت عمومی منتشر میشه و این امر باعث میشه تا  ما با آپدیت هایی مطمئن و کارامد طرف باشیم.2. Server Componentsدر حال حاضر کامپوننت های ری اکتی در سمت client یا همان کاربر رندر و  اجرا میشن، اما در ورژن جدید ری اکت، یعنی ری اکت 19 ما قادر خواهیم بود تا  کامپوننت هارو در سمت سرور هم رندر کنیم.ما server side rendering را از خیلی وقت پیش در NextJS داشتیم و این  قابلیت اخیر که هر کامپوننتی که مدنظرمون بود را تبدیل به server component  بکنیم هم از NextJS 13 به بعد ( دقیقا بعد از اینکه ری اکت این قابلیت را  در نسخه canary معرفی کرد ) هم به NextJS اضافه شد و حالا از NextJS 13 به  بعد تمام کامپوننت ها بصورت پیشفرض server component هستند.این قابلیت هم که قرار در ری اکت 19 بصورت رسمی اضافه بشه تا ما بدون  نیاز به ابزار یا فریمورک جداگانه ای مثل NextJS بتونیم ازش استفاده کنیم.  برخی از مزیت های رندر کامپوننت در سمت سرور میشه به موارد زیر اشاره کرد:SEO: برای اینکه صفحات ما در دسترس ربات های گوگل  قرار بگیرند، نیازه تا به محض ورود ربات گوگل به صفحه ما، html اون صفحه در  اختیار اون ربات قرار بگیره،در نتیجه رندر کامپوننت در سمت سرور باعث میشه  تا اول تمام html اماده بشه و بعد صفحه بارگذاری بشه و در نتیجه به محض  بارگذاری صفحه، تمام محتوا در اختیار ربات گوگل قرار میگیره.Performance: سرور کامپوننت ها سرعت بارگذاری اولیه بالاتری دارند و این عملکرد خودش را در صفحات سنگین تر به خوبی نشون میده.اجرای کد در سرور: طبیعتا اولین و مهم ترین مزیت هم  اجرای کد در سمت سرور و قبل از رسیدن کار به سمت کاربر هستش. ما میتونیم  api کال های مهمی را در سمت سرور داشته باشیم و بعد تصمیم بگیریم در سمت  کاربر چه اتفاقی بیوفته!همانطور که قبل تر هم گفتیم، تمام کامپوننت ها در ری اکت 19 بطور پیشفرض  در سمت کاربر اجرا خواهند شد و برای اینکه یک کامپوننت را به سرور  کامپوننت تبدیل کنیم، نیاز داریم تا در اولین خط از کامپوننت خودمون عبارت &quot;use server&quot; را بنویسیم.3. actionsدر نسخه 19 ری اکت، یکی دیگه از تغییرات جذاب و کاربردی که داریم action  ها هستند و بوسیله این action ها میتونیم با قدرت بیشتری با فرم ها کار  کنیم و در این نسخه میتونیم جای  را با form action جابجا کنیم.قبل از actions:در مثال زیر ما فرمی را داریم که فقط با صدا زده شدن یک event یعنی   اجرا میشه و سرچ ما زمانی زده میشه که فرم ما ثبت شده باشه. این  مارو به استفاده از event های ری اکتی که در سمت کاربر وجود دارند محدود  میکنه و نمیتونیم این فرم را در سمت سرور اجرا کنیم.&lt;form ={search}&gt;
  &lt;input name=&amp;quotquery&amp;quot /&gt;
  &lt;button type=&amp;quotsubmit&amp;quot&gt;Search&lt;/button&gt;
&lt;/form&gt;بعد از actions:با معرفی ری اکت 19 میتونیم فرم اکشن خودمون را بوسیله اتریبیوت action  فرم ها و در سمت سرور اجرا کنیم و لازم به ذکر که هم میتونیم بصورت sync و  هم بصورت async اینکارو انجام بدیم. هدف هم سادست، مدیریت بهتر state ها و  داده ها و ساده سازی ثبت فرم ها.&amp;quotuse server&amp;quot

const submitData = async (userData) =&gt; {
    const newUser = {
        username: userData.get(&#039;username&#039;),
        email: userData.get(&#039;email&#039;)
    }
    console.log(newUser)
}const Form = () =&gt; {
    return &lt;form action={submitData}&gt;
        &lt;div&gt;
            &lt;label&gt;Name&lt;/label&gt;
            &lt;input type=&amp;quottext&amp;quot name=&#039;username&#039;/&gt;
        &lt;/div&gt;
        &lt;div&gt;
            &lt;label&gt;Name&lt;/label&gt;
            &lt;input type=&amp;quottext&amp;quot name=&amp;quotemail&amp;quot /&gt;
        &lt;/div&gt;
        &lt;button type=&#039;submit&#039;&gt;Submit&lt;/button&gt;
    &lt;/form&gt;
}

export default Form;در کد بالا، submitData در واقع action ما در سرور کامپوننت هست و فرم ما هم کامپوننت سمت کلاینت ما هستش که داره از submitData به عنوان action استفاده میکنه. این submitData در سمت سرور اجرا خواهد شد و این برقراری ارتباط submitData که در سمت سرور وجود داره و فرمی که در سمت کلاینت هست فقط به لطف action ها و در ری اکت 19 ممکن خواهد بود.در ادامه این مقاله هم قراره با چندتا هوک جدید آشنا بشیم که دست مارو  در کار با فرم ها و action ها باز تر میزاره و قدرت بیشتری هم بهمون میده.4. Web Componentsوب کامپوننت ها به ما اجازه میدن تا بوسیله Html, Css و Javascript  کامپوننت هایی بسازیم که میشه ازشون مثل یک تگ واقعی و استاندارد html ازش  استفاده کرد.در حال حاضر امکان استفاده از وب کامپوننت ها بصورت مستقیم و بدون  استفاده از ابزارهای خارجی وجود نداره و تلفیق وب کامپوننت ها با کامپوننت  های ری اکتی هم اصلا کار ساده ای نیست.خبر خوب اینه که این قضیه موقتیه و با انتشار ری اکت 19 خیلی راحت تر  میتونیم وب کامپوننت هارو در کامپوننت های ری اکتی خودمون استفاده کنیم.فعلا اطلاعات بیشتری از سینتکس و نحوه کار این ویژگی در ری اکت 19 وجود  نداره و صرفا امیدواریم که به راحت ترین شکل ممکن این مورد در اختیار ما  قرار بگیره 😬5. Document Metadataاکثر وبسایت ها به SEO نیاز دارن تا بتونن بهتر در نتایج گوگل ظاهر بشن و  مخاطب خودشون را جذب کنند و تا به امروز امکان افزودن متا تگ های مانند  title, description و ... بطور مستقیم و بدون نیاز به کدهای اضافی و پکیج  های خارجی ممکن نبود و امروز به لطف ری اکت 19 میتونیم به راحتی آب خوردن و  بدون هیچ دردسری هر متا تگی که دلمون میخواد را در صفحات خودمون استفاده  کنیم.Const HomePage = () =&gt; {
  return (
    &lt;&gt;
      &lt;title&gt;vaspar&lt;/title&gt;
      &lt;meta name=&amp;quotdescription&amp;quot content=&amp;quotvaspar blogs&amp;quot /&gt;
      // Page content
    &lt;/&gt;
  );
}6. Asset Loadingمعمولا در ابتدای کار یک view ساده از صفحه وب ما در مرورگر رندر میشه و  سپس بدنبالش stylesheets, fonts, و image ها بارگذاری میشن و این امر باعث  میشه که برای چند لحظهui بدون استایل و یا ui که نامرتب و با استایل های  نصفه و نیمه هستش را ببینیم. توسعه دهنده ها برای مدیریت این مشکل، کدهای  اضافی مینویسن تا بتونن بارگذاری شدن کامل این موارد را تشخیص بدن و بعد از  بارگذاری کامل اونهارو به دید کاربر در بیارن ( مثلا یک skeleton loading  را به جای یک عکس نمایش میدن )در ری اکت 19 این فایل ها، عکس ها یا هر نوع دیگه ای از asset ها هم در  background بارگذاری میشن و هم دارای lifecycle Suspense هستند و این به آن  معناست که بارگذاری شدن asset های ما هم بهینه تر میشن و هم به راحتی  میتونیم زمان کامل load شدنشون را تشخیص بدیم.همچنین یکسری Resource Loading API جدید مثل preload و preinit را هم خواهیم داشت که کنترل بیشتری به ما میده و میتونیم تعیین کنیم که Asset مدنظر ما چه زمان و به چه شکلی بارگذاری بشن.با بارگذاری شدن asset ها در background و بصورت async هم مدت زمان  بارگذاری صفحات ما کوتاه تر میشه و هم با بهم ریختگی اولیه ui مواجه  نخواهیم شد و این تجربه خیلی بهتری را به کاربران وبسایت ما میده.7. هوک های جدیدهوک ها از دوست داشتنی ترین قابلیت های ری اکت هستند و همه ما دفعات  خیلی زیادی از Built-in Hook ها و custom hook ها در پروژه های ری اکتی  خودمون استفاده کردیم. در ری اکت 19 یکسری از این هوک ها قراره تغییراتی در  استفاده ازشون بوجود بیاد و هوک هایی مثل useMemo, forwardRef, useEffect, و  useContext قراره پس از معرفی شدن هوک جدید use تغییراتی را داشته باشند.useMemoدر ری اکت 19 دیگه نیازی به استفاده از useMemo نیست و ری اکت کامپایلر  قراره این کار را در پشت صحنه برای ما انجام بده. بریم در ادامه دوتا مثال  از قبل ری اکت 19 که مجبور به استفاده از useMemo بودیم و بعدش که دیگه  نیازی بهش نداریم را ببینیم:قبل:import React, { useState, useMemo } from &#039;react&#039;;

function ExampleComponent() {
  const [inputValue, setInputValue] = useState(&#039;&#039;);

  // Memoize the result of checking if the input value is empty
  const isInputEmpty = useMemo(() =&gt; {
    console.log(&#039;Checking if input is empty...&#039;);
    return inputValue.trim() === &#039;&#039;;
  }, [inputValue]);

  return (
    &lt;div&gt;
      &lt;input
        type=&amp;quottext&amp;quot
        value={inputValue}
        ={(e) =&gt; setInputValue(e.target.value)}
        placeholder=&amp;quotType something...&amp;quot
      /&gt;
      &lt;p&gt;{isInputEmpty ? &#039;Input is empty&#039; : &#039;Input is not empty&#039;}&lt;/p&gt;
    &lt;/div&gt;
  );
}

export default ExampleComponent;بعد:import React, { useState } from &#039;react&#039;;

function ExampleComponent() {
  const [inputValue, setInputValue] = useState(&#039;&#039;);

  const isInputEmpty = () =&gt; {
    console.log(&#039;Checking if input is empty...&#039;);
    return inputValue.trim() === &#039;&#039;;
  });

  return (
    &lt;div&gt;
      &lt;input
        type=&amp;quottext&amp;quot
        value={inputValue}
        ={(e) =&gt; setInputValue(e.target.value)}
        placeholder=&amp;quotType something...&amp;quot
      /&gt;
      &lt;p&gt;{isInputEmpty ? &#039;Input is empty&#039; : &#039;Input is not empty&#039;}&lt;/p&gt;
    &lt;/div&gt;
  );
}

export default ExampleComponent;forwardRefدر ری اکت 19 دیگه به forwardRef هم نیازی نیست چراکه میتونیم به راحتی ref مدنظرمون را از طریق props پاس بدیم به کامپوننت مدنظرمون!قبل:قبل از react 19 مجبور بودیم که ref هارو به شکل زیر و بوسیله forwardRef به کامپوننت مدنظرمون بدیم:import React, { forwardRef } from &#039;react&#039;;

const ExampleButton = forwardRef((props, ref) =&gt; (
  &lt;button ref={ref}&gt;
    {props.children}
  &lt;/button&gt;
));بعد:اما در ورژن جدید ری اکت، میتونیم به راحتی ref مدنظر را از طریق props پاس بدیم:import React from &#039;react&#039;;

const ExampleButton = ({ ref, children }) =&gt; (
  &lt;button ref={ref}&gt;
    {children}
  &lt;/button&gt;
);هوک جدید useدر ری اکت 19 یک هوک جدید با نام use خواهیم داشت و این هوک قراره کار  با promise ها, کدهای async و context را راحت تر کنه. سینتکس این هوک به  شکل زیره:const value = use(resource);در مثال زیر هم متونیم یک مثال واقعی تر از یک http get request را بوسیله هوک use ببینیم:import { use } from &amp;quotreact&amp;quot

const fetchUsers = async () =&gt; {
    const res = await fetch(&#039;https://jsonplaceholder.typicode.com/users&#039;);
    return res.json();
  };
  
  const UsersItems = () =&gt; {
    const users = use(fetchUsers());
  
    return (
      &lt;ul&gt;
        {users.map((user) =&gt; (
          &lt;div key={user.id} className=&#039;bg-blue-50 shadow-md p-4 my-6 rounded-lg&#039;&gt;
            &lt;h2 className=&#039;text-xl font-bold&#039;&gt;{user.name}&lt;/h2&gt;
            &lt;p&gt;{user.email}&lt;/p&gt;
          &lt;/div&gt;
        ))}
      &lt;/ul&gt;
    );
  }; 
export default UsersItems;بریم کد بالارو بشکافیم و ببینیم چطور و چکاری را داره انجام میده:کار فانکشن fetchUsers دریافت لیست کاربران از سروری هست که آدرسش را بهش دادیم.قبلتر نیاز بود تا فانکشن fetchUsers را در useEffect صدا کتیم و سپس مقدارش را در یک state ذخیره کنیم اما حالا هوک use هردوی این کارهارو برای ما انجام میده.در نهایت هم که جواب fetchUsers ما در قالب return هوک use که ما اونرو در متغیر users ذخیره کردیممزیتی که این هوک به ما میده اینه که میتونیم فانکشن هایی که مسئول کار  با api ها هستند را در یک فایل جداگانه ذخیره کنیم و به راحتی و با کدی  کمتر و بدون نیاز به state و useEffect اونهارو اجرا کنیم.برای استفاده از context هم حتی میتونیم از هوک use استفاده کنیم:const Card = () =&gt; {
  // use Hook()
  const { theme, toggleTheme } = use(ThemeContext);

  return (
    &lt;div
      className={`p-4 rounded-md ${
        theme === &#039;light&#039; ? &#039;bg-white&#039; : &#039;bg-gray-800&#039;
      }`}
    &gt;
      &lt;h1
        className={`my-4 text-xl ${
          theme === &#039;light&#039; ? &#039;text-gray-800&#039; : &#039;text-white&#039;
        }`}
      &gt;
        Theme Card
      &lt;/h1&gt;
      &lt;p className={theme === &#039;light&#039; ? &#039;text-gray-800&#039; : &#039;text-white&#039;}&gt;
       Hello!! use() hook
      &lt;/p&gt;
      &lt;button
        ={toggleTheme}
        className=&#039;bg-blue-500 hover:bg-blue-600 text-white rounded-md mt-4 p-4&#039;
      &gt;
        {theme === &#039;light&#039; ? &#039;Switch to Dark Mode&#039; : &#039;Switch to Light Mode&#039;}
      &lt;/button&gt;
    &lt;/div&gt;
  );
};هوک جدید useFormStatusبوسیله این هوک میتونیم کنترل بیشتری برروی آخرین فرم ثبت شده شده خودمون داشته باشیم.const { pending, data, method, action } = useFormStatus();pending: اطلاع از در حال ثبت بودن یا نبودن فرم.data: یک FormData آبجکت که شامل مقادیر فیلدهایی هست که داخل تگ form ما قرار دارند.method: شامل http method ثبت فرم ما هستش. مثلا GET یا POST بودنش.action: یک رفرنس از فانکشنی که به اتریبیوت action فرممون پاس دادیم اینجا هم در اختیار ما قرار میگیره.بریم یک مثال هم از این هوک جدیدی که در  ری اکت 19 قراره داشته باشیمش ببینیم:import { useFormStatus } from &amp;quotreact-dom&amp;quot

function Submit() {
  const status = useFormStatus();
  return &lt;button disabled ? &#039;Submitting...&#039; : &#039;Submit&#039;}&lt;/button&gt;;
}

const formAction = async () =&gt; {
  // Simulate a delay of 2 seconds
  await new Promise((resolve) =&gt; setTimeout&#40;resolve, 3000&#41;);
}

const FormStatus = () =&gt; {
  return (
    &lt;form action={formAction}&gt;
      &lt;Submit /&gt;
    &lt;/form&gt;
  );
};

export default FormStatus;هوک useFormStateیک هوک دیگه که قراره در ری اکت 19 داشته باشیم، useFormState هست که به ما اجازه میده یک state را طبق ثبت شدن یک فرم آپدیت کنیم.const [state, formAction] = useFormState(fn, initialState, permalink?);fn: یک فانکشن برای زمانیکه فرم ثبت بشه.initialState: مقدار اولیه state ماpermalink: یک آپشن اختیاری که میتونیم بوسیلش تعیین کنیم درصورت اجرا شدن fn در سمت سرور، کاربر را به چه صفحه ای ریدایرکت کنه.state: مقدار state ما هست و در اول کار هم که مساوی با initialState خواهد بود.formAction: یک action که به اتریبیوت action فرم ما پاس داده میشه و مقداری که return میکنه هم در state در دسترس خواهد بود.یک مثال هم از نحوه کار این هوک:import { useFormState} from &#039;react-dom&#039;;

const FormState = () =&gt; {
    const submitForm = (prevState, queryData) =&gt; {
        const name =  queryData.get(&amp;quotusername&amp;quot);
        console.log(prevState); // previous form state
        if(name === &#039;john&#039;){
            return {
                success: true,
                text: &amp;quotWelcome&amp;quot
            }
        }
        else{
            return {
                success: false,
                text: &amp;quotError&amp;quot
            }
        }
    }
    const [ message, formAction ] = useFormState(submitForm, null)
    return &lt;form action={formAction}&gt;
        &lt;label&gt;Name&lt;/label&gt;
        &lt;input type=&amp;quottext&amp;quot name=&amp;quotusername&amp;quot /&gt;
        &lt;button&gt;Submit&lt;/button&gt;
        {message &amp;&amp; &lt;h1&gt;{message.text}&lt;/h1&gt;}
    &lt;/form&gt;
}

export default FormState;هوک useOptimisticبوسیله این هوک میتونیم قبل از رسیدن جوابی برای عملیات های async پیغام  یا یک state را به کاربر نشان بدیم. این هوک باعث میشه تا تجربه کاربری  کمی بهتر بشه و سرعت نمایش پاسخ عملیات های async مثل http requests را  بیشتر ( یجورایی لحظه ای میکنه )const [ optimisticMessage, addOptimisticMessage] = useOptimistic(state, updatefn)روشی به نام آپدیت خوشبینانه ( optimistic update ) داریم که در این  روش ما قبل از تکمیل شدن مثلا یک درخواست http post میاییم نتیجه را در  لحظه به کاربر نشان میدیم. به عنوان مثال وقتی کاربر کامنت جدیدی رو ثبت  میکنه ما منتظر جواب بک اند نمیمونیم و فرض را بر موفقیت آمیز بودن ثبت  کامنتش میزاریم ( رو همین حساب بهش میگیم آپدیت خوشبینانه ) و در لحظه  کامنتی که ثبت کرده را در لیست کامنت ها نمایش میدیم و در پشت صحنه لیست  کامنت هارو بروز میکنیم تا مطمعن هم بشیم که کامنت کاربر بصورت موفقیت آمیز  ثبت شده باشه.بریم یک مثال هم از این هوک ببینیم:import { useOptimistic, useState, useRef } from &amp;quotreact&amp;quot

async function deliverMessage(message) {
  await new Promise((res) =&gt; setTimeout&#40;res, 1000&#41;);
  return message;
}

function Thread({ messages, sendMessage }) {
  const formRef = useRef();
  async function formAction(formData) {
    addOptimisticMessage(formData.get(&amp;quotmessage&amp;quot));
    formRef.current.reset();
    await sendMessage(formData);
  }
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage) =&gt; [
      ...state,
      {
        text: newMessage,
        sending: true,
      },
    ]
  );

  return (
    &lt;&gt;
      {optimisticMessages.map((message, index) =&gt; (
        &lt;div key={index}&gt;
          {message.text}
          {!!message.sending &amp;&amp; &lt;small&gt; (Sending...)&lt;/small&gt;}
        &lt;/div&gt;
      ))}
      &lt;form action={formAction} ref={formRef}&gt;
        &lt;input type=&amp;quottext&amp;quot name=&amp;quotmessage&amp;quot placeholder=&amp;quotHello!&amp;quot /&gt;
        &lt;button type=&amp;quotsubmit&amp;quot&gt;Send&lt;/button&gt;
      &lt;/form&gt;
    &lt;/&gt;
  );
}

export default function App() {
  const [messages, setMessages] = useState([
    { text: &amp;quotHello there!&amp;quot, sending: false, key: 1 },
  ]);
  async function sendMessage(formData) {
    const sentMessage = await deliverMessage(formData.get(&amp;quotmessage&amp;quot));
    setMessages((messages) =&gt; [...messages, { text: sentMessage }]);
  }
  return &lt;Thread messages={messages} sendMessage={sendMessage} /&gt;;
}این مثال در داکیومنت خود ری اکت زده شده و میتونید خروجی این مثال را هم در این لینک ببینید.آیا میشه الان از ری اکت 19 استفاده کرد ؟در حال حاضر تمام ویژگی های جدیدی که در این مقاله دربارشون خواندیم، در  نسخه canary ری اکت وجود داره و ورژن 19 ری اکت هنوز بطور رسمی منتشر  نشده. طبق توصیه داکیومنت ری اکت، بهتره که از نسخه های canary در پروژه  های مهم استفاده نکنید و صرفا جهت یادگیری و گشت و گذار در دل ویژگی های  جدید ری اکت از اونها استفاده کنید. همچنین این نسخه از ری اکت را قراره در دوره آموزش فرانت اند هم بطور کامل آموزش بدیم.منبع: https://vaspar.io/blog/react-19-overview</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Wed, 10 Apr 2024 17:19:32 +0330</pubDate>
            </item>
                    <item>
                <title>برسی منطقه مرده زمانی در جاوااسکریپت</title>
                <link>https://virgool.io/vaspar/tdz-in-javascript-ctippkjebv9q</link>
                <description>اصطلاحی عجیب به نام منطقه مرده زمانی که حتی ممکنه پس از چندین سال کار کردن با جاوااسکریپت هم  اونرو نشنیده باشید و امروز در این مقاله قصد داریم تا نگاهی کامل بهش  بندازیم و در قدم اول ببینیم که اصلا TDZ یا همان منطقه مرده زمانی چی هست و  چه تاثیری برروی کد ما میزاره.منطقه مرده زمانی در جاوااسکریپت چیست ؟مرحله ای از اجرای کدها در پشت صحنه که متغیرهای ما وجود دارند، اما  هنوز قابل استفاده و دسترسی ما نیستند را منطقه مرده زمانی مینامیم و در  زمانیکه یک متغیر در منطقه مرده زمانی قرار داره، هر تلاشی برای دسترسی و  استفاده از اون متغیر، مارو با ارور referenceError مواجه میکنه. این مفهوم و رفتار هم فقط برای متغیرهایی وجود داره که با کلمه let یا const تعریف شده باشند و این مفهوم برای متغیرهای var وجود نداره.console.log(myWebsite); // Output: ReferenceError: Cannot access &#039;myWebsite&#039; before initialization

let myWebsite = &amp;quotwww.vaspar.io&amp;quotدر مثال بالا، اومدیم قبل از تعریف شدن متغیر myWebsite  یعنی زمانیکه این متغیر توی منطقه مرده زمانی بود ازش استفاده کردیم و در  نتیجه با ارور مواجه شدیم. هدف این رفتار فقط برای متغیرهای ایجاد شده با let و const هستش و به ما اجازه دسترسی به متغیرها، قبل از تعریف شدنشون را نمیده تا برخلاف متغیرهای قدیمی var که قبل از تعریف شدن هم میتونستیم ازشون استفاده کنیم، مطمعن بشه که کدی مطمئن و تمیز مینویسیم.منطقه مرده زمانی و متغیرهای varاین رفتار برروی همه متغیرهای جاوااسکریپتی یکسان نیست و از اونجایی که متغیرهای ایجاد شده با var در زمان اجرای کد، بصورت اسمی و ظاهری به بالای scope منتقل میشن ( hoist میشن )  این رفتار فقط برای متغیرهای ایجاد شده با let و const وجود داره و اگر یک متغیری را با کلمه var در خط 2 تعریف کنیم و بخواهیم ازش در خط 1 استفاده کنیم، با هیچ ارور و  مشکلی مواجه نمیشیم و تنها اتفاقی که میوفته اینه که مقدار اون متغیر var برابر با undefined خواهد بود.console.log(myWebsite); // Output: undefined

var myWebsite = &amp;quotwww.vaspar.io&amp;quotبخاطر داشته باشید که ما از اصطلاح زمان استفاده میکنیم نه محدوده ...دقت کنید که ما میگیم منطقه مرده زمانی، نه محدوده مرده زمانی! یعنی چی ؟  یعنی اینکه اگر شما در یک فانکشنی، از متغیری که هنوز ایجاد نشده استفاده  کنید و بعد از جاییکه اون متغیر ایجاد شد ازش استفاده کنید، دیگه با ارور  مواجه نمیشید و کد شما به درستی کار میکنه و خبریم از منطقه مرده زمانی  نخواهد بود:{
  // shorooe TDZ
  const func = () =&gt; console.log(letVar); // OK

  // agar inja va ghabl az tarife letVar function ra seda bezanim error migirim

  let letVar = 3; // TDZ inja tamoom mishe
  func(); // code ro dige kharej az TDZ seda zadim va hame chiz ok hastesh
}در مثال بالا ما فانکشنی داریم با نام func و در این فانکشن داریم از متغیری به نام letVar استفاده میکنیم که این متغیر چند خط بعد تر از فانکشن ما تعریف شده و بعد از محل تعریف شدن متغیر letVar هم میاییم فانکشن func را اجرا میکنیم. در این کد هیچ مشکلی وجود نخواهد داشت چراکه ما زمانی  فانکشن خودمون را اجرا کردیم که متغیر مدنظر ما تعریف و مقدار دهی شده!چطور از این رفتار دوری کنیم ؟برای اینکه توی کدهامون با منطقه مرده زمانی یا TDZ روبرو نشیم، یکسری کارهای ساده را باید انجام داد:همیشه متغیرهای مدنظر خودرا، قبل از محلی که ازش استفاده کردید، تعریف کنید.scope ها در جاوااسکریپت را بشناسید، متغیرهای ایجاد شده با let و const اصطلاحا block scope هستند و ازشون فقط در محدوده ای که تعریف شدن میشه  استفاده کرد ( مثلا فقط در فانکشنی که تعریفشون کردیم قابل دسترسین )از متغیرهای var دوری کنید و یا با احتیاط ازشون استفاده کنید. باوجود اینکه متغیرهای var به بالای scope منتقل میشن و منطقه مرده زمانی براشون وجود نداره، بازهم  سعی کنید ازشون استفاده نکنید. حتما دلیلی داشته که با گذشت زمان متغیرهای let و const به جاوااسکریپت اضافه شدن!از ابزارهایی مثل ESLint استفاده کنید، این ابزارها مطمئن میشن تا شما کدی تمیز، مطمئن و طبق آخرین اصول های موجود بنویسید.سخن پایانی ...متوجه شدیم که منطقه مرده زمانی، به مرحله ای از اجرای کدها در پشت صحنه  گفته میشه که در اون مرحله متغیرهای ما وجود دارند، اما غیر قابل دسترس  اند و اگر بخواهیم قبل از جاییکه متغیر ما تعریف شده ازش استفاده کنیم، با  ارور referenceError مواجه میشیم.همچنین فهمیدیم که بدلیل مکانیزم hoisting در جاوااسکریپت، منطقه مرده زمانی فقط برای متغیرهای let و const وجود داره و این قضیه برای متغیرهای var صدق نمیکنه.نکته مهمیم که بهش اشاره کردیم، این بود که ما داریم به زمان اشاره  میکنیم نه مکان یا محدوده، بنابر این اگر در یک فانکشنی از متغیری که هنوز  تعریف نشده استفاده کنیم و بعد از جایی که اون متغیر تعریف شده فانکشنمون  را اجرا کنیم، دیگه به منطقه مرده زمانی بر نخواهیم خورد و کد ما بدون هیچ  اروری کار خواهد کرد.امیدوارم این مقاله براتون کاربردی و مفید بوده باشه و پیشنهاد میکنم نگاهی هم به دوره آموزش Frontend ما بندازید، تو این دوره سعی کردیم در مسیری متفاوت و مدرن فرانت اند را به شما آموزش بدیم.منبع: https://vaspar.io/blog/temporal-dead-zone-in-javascript</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Tue, 02 Apr 2024 18:19:34 +0330</pubDate>
            </item>
                    <item>
                <title>نسخه آلفا Tailwind CSS v4.0 منتشر شد.</title>
                <link>https://virgool.io/vaspar/tailwindcss-v40-alpha-txrhyfosns55</link>
                <description>تابستان سال گذشته، پیش نمایشی از Engine جدید و قدرتمند Tailwindcss با نام Oxide منتشر شد و حالا پس از مدتی توسعه، این Engine جدید که عملکرد خیلی بهتری داره در قالب ارائه اولیه ( آلفا ) ورژن 4 منتشر شده. قدرتمند تر و کارامد تر شدن به لطف Engine جدید:تا 10 برابر سریعتر: با این Engine زمان بیلد یک وبسایت کامل از 960ms به 105ms رسیده!سبک و کم حجم: 35% سبک تر با وجود قدرتمند تر شدن Engine جدید!کارایی بهتر به لطف Rust: برخی از محاسبات سنگین این ورژن با زبان Rust پیاده شدن و در نتیجه شاهد عملکرد و کارایی بهتری خواهیم بود.حذف وابستگی های اضافه: تنها Dependency این ورژن Lighting CSS خواهد بود.پارسر اختصاصی: این Parser اختصاصی نسبت به قبلیه خودش یعنی PostCSS تا 2 برابر سریعتر خواهد بود.طراحی شده برای هرچه مدرن تر و کارامد تر بودن:کنترل بهتر استایل ها: به لطف ساپورت cascade layers بصورت native, دیگه بوسیله layer@ میتونیم کنترل بهتر و دقیق تری رو برروی استایل هامون داشته باشیم.کنترل سایز هر تگ HTML: به لطف container query هایی چون *-min@ و *-max@ دیگه میتونیم بصورت native استایل های متفاوتی را طبق تغییر سایز هر المانی مثل یک تگ div اعمال کنیم ( یچیزی تو مایه های media query هستش )تعریف و ایجاد پراپرتی های دلخواه: بوسیله property@ میتونیم پراپرتی های دلخواه خودمون را تعریف کنیم. مثلا میشه از این قابلیت برای اعمال Transition روی یک background gradiet استفاده کنیم.یکپارچه سازی و حذف کانفیگ ها و وابستگی های اضافی:تو این ورژن تنها Dependency که برای Tailwind وجود داره Lighting CSS هست و خیلی از چیزها بصورت Native ساپورت میشن. مثلا import@ را داریم و مثل گذشته برای پیاده سازیش دیگه به کانفیگ postcss-import نیازی نیست.همچنین خیلی از پلاگین های دیگه مثل autoprefixer رو هم تو این ورژن بهشون نیازی نخواهیم داشت.دیگه تو این ورژن چیا داریم ؟این ورژن امکانات جدید و تغییرات زیادی را داره و برخی از مهم ترینه این تغییرات رو در بالا به اختصار شرح دادیم، برای مطالعه کامل تر تغییرات این نسخه میتونید به وبسایت رسمی Tailwind که لینکش را در انتهای این پست قرار دادیم مراجعه کنید. همچنین به محض انتشار رسمی این ورژن، یک مقاله ای جهت بررسی و معرفی کامل این نسخه آماده خواهیم کرد.منبع: https://tailwindcss.com/blog/tailwindcss-v4-alphaراستی یک دوره متفاوت آموزش فرانت اند رو شروع کردیم و تو این دوره قراره فرانت اند را طی مسیری مدرن و خاص به پشتوانه roadmap فرانت اند وبسایت roadmap.sh یاد بگیریم، دوست داشتید نگاهی هم به این دوره بندازید:)https://vaspar.io/courses/frontend</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Mon, 25 Mar 2024 22:43:00 +0330</pubDate>
            </item>
                    <item>
                <title>آموزش کامل Hoisting در جاوااسکریپت</title>
                <link>https://virgool.io/codenevis/what-is-javascript-hoisting-mmvysbweabsb</link>
                <description>ا hoisting به پروسه ایی گفته میشه که در آن مفسر کد جاوااسکریپت قبل از اجرای کد و  بصورت ظاهری محل تعریف شدن یک فانکشن، متغیر یا کلاس رو به بالای scope  منتقل میکنه و این رفتار پیشفرضی که جاوااسکریپت از خودش نشون میده باعث  میشه تا ما بتونیم حتی قبل از محل نوشته شدن یک فانکشن از اون استفاده  کنیم.نکته: جاوااسکریپت بصورت ظاهری فقط محل تعریف شدن یک متغیر را به بالای scope منتقل میکنه، نه مقدار اون متغیر را.همچنین جاوااسکریپت قبل از اجرا شدن کد، memory لازم را به فانکشن ها و متغیرها اختصاص میده.ترتیب و چرخه متغیرها در جاوااسکریپتدر مواجه با متغیرها ما یک تعریف متغیر، مقداردهی متغیر و درنهایت استفاده از اون متغیر رو داریم، یعنی چیزی مثل کد زیر:let a;                  // تعریف متغیر
a = 100;            // مقدار دهی متغیر
console.log(a);  // استفاده از متغیردر مثال بالا صرفا برای نشون دادن چرخه و ترتیب متغیرها در جاوااسکریپت  از تعریف و مقداردهی جداگانه استفاده کردیم و بجای کد بالا میتونیم همزمان  متغیر را ایجاد و مقداردهی کنیم:let a = 100;البته این نکته را به خاطر داشته باشید که جاوااسکریپت در پشت صحنه و  قبل از اجرا شدن کد همانند مثال اول ابتدا متغیر را تعریف و سپس مقدارد دهی  میکنه.یک حالت متفاوتی هم وجود داره، فرض کنید شما هیچوقت متغیری با نام a بوسیله var یا let یا const تعریف نکردید، ولی در جایی از کد خودتون به شکل زیر a را مقدار دهی میکنید:function hoist() {
  a = 20;
  var b = 100;
}

hoist();

console.log(a); 
/* 
خروجی : 20
be onvane yek variable global dar nazar gerefte mishe
*/

console.log(b); 
/*
خروجی: ReferenceError: b is not defined
chon ba kalame var daroone function hoist tarif shode. scope oonham mahdood be function hast
*/در کد بالا متغیر a به عنوان یک متغیر global در نظر گرفته میشه، بنابر  این اینگونه متغیرهایی که قبلا تعریف نشدند به عنوان متغیرهای global  شناخته میشن و این یکی از عجیب ترین کارهایی هست که جاوااسکریپت در مواجه  با متغیرها انجام میده و از اینرو توصیه میشه تا همیشه متغیر مدنظر خودتون  را در scope مدنظرتون تعریف کنید تا هم خوانایی کد بالاتر بره و هم از صحت و  عملکرد کد خیالتون راحت باشه!hoisting متغیرها در جاوااسکریپتvar hoistingscope متغیرهای var زمینه اجرای فعلی اونهاست. یعنی چی ؟ یعنی اگر متغیری با کلمه var درون یک فانکشن ایجاد کنید، scope اون متغیر محدود به فانکشنی هست که در  اون محصور شده و اگر خارج از هرگونه فانکشنی تعریفشون کنید، scope اونها  global خواهد بود. بیایید چند مثال را باهم ببینیم:متغیرهای globalconsole.log(hoist); // خروجی: undefined

var hoist = &#039;variable hoist shod&#039;;ما پیش خودمون فکر میکردیم خروجی کد بالا مساوی با ارور ReferenceError: hoist is not defined خواهد بود اما چنین نشد و بجاش با مقدار undefined روبرو شدیم! فکر میکنید دلیلش چیه ؟دلیل اینکه در کد بالا با اروری مواجه نشدیم این هست که جاوااسکریپت محل  تعریف شدن متغیر را ( variable declaration ) را قبل از اجرای هرگونه کدی  به بالای scope منتقل کرد و اگر بخواهیم رفتار مفسر کد جاوااسکریپت در  مواجه با کد بالا را شبیه سازی کنیم، میتونیم مثال زیر رو بزنیم:var hoist;

console.log(hoist); // خروجی: undefined
hoist = &#039;variable hoist shod&#039;;از اینرو ما میتونیم از متغیرها قبل از تعریف شدنشون هم استفاده کنیم،  هرچند باید به خاطر داشت که مقدار متغیرهایی که قبل از تعریف شدنشون داریم  ازشون استفاده میکنیم بصورت پیشفرض برابر با undefined خواهد  بود و توصیه ما این هست که همیشه قبل از استفاده از یک متغیر اونرو تعریف و  مقدار دهی کنید تا کد تمیزتر و قابل اطمینان تری داشته باشید.Function scoped variablesهمانطور که بالاتر دیدیم، متغیرهای global-scope به بالاترین سطح hoist  میشن. حالا بیایید باهم ببینیم که متغیرهای function-scope به چه صورت عمل  میکنند و چگونه hoist میشن.function hoist() {
  console.log(message);
  var message=&#039;hello world&#039;
}

hoist();طبق چیزهایی که تا اینجای مقاله باهم یادگرفتیم حدس بزنید که خروجی کد بالا چی خواهد بود ؟اگر حدس شما مقدار undefined هست که تبریک میگم! تا اینجای  مقاله را خوب متوجه شدید و اگرهم حدستون اشتباه بوده که جای هیچ نگرانی  نیست چراکه در ادامه مقاله به توضیح و برسی بیشتری میپردازیم.کد زیر شکلی هست که مفسر جاوااسکریپت کد بالا رو میبینه:function hoist() {
  var message;
  console.log(message);
  message=&#039;hello world&#039;
}

hoist(); // خروجی: undefinedscope متغیر message فانکشن hoist هست، بنابر این متغیر message به  بالای scope فانکشن hoist منتقل میشه و برای جلوگیری از مواجه شدن با مقدار  undefined بهتر هست که ابتدا متغیر را تعریف و مقدار دهی کنیم و سپس از  اون استفاده کنیم، یعنی به شکل زیر:function hoist() {
  var message=&#039;hello world&#039;
  return (message);
}

hoist(); // خروجی: hello worldstrict mode و var hoistingبه لطف ابزاری از نسخه es5 جاوااسکریپت که به عنوان strict mode شناخته  میشه، میتونیم با حالت سختگیرانه تری متغیرهامون را تعریف کنیم. با فعال  سازی حالت strict mode ما وارد یک حالت محدود تری از جاوااسکریپت میشیم که  اجازه استفاده از یک متغیر را قبل از تعریف شدنش نمیده!بطور کل استفاده از حالت strict mode تغییرات زیر را به همراه داره:در این حالت برخی از ارورهای اصطلاحا خاموش دیگه توسط جاوااسکریپت نادیده گرفته نمیشن.اشتباهاتی که بهینه سازی را برای موتورهای جاوااسکریپتی سخت میکنه را اصلاح میکنه.استتفاده از برخی syntax هایی که ممکنه در نسخه های آینده جاوااسکریپت اضافه بشه را منع میکنه.حالت strict mode را میتونیم با نوشتن عبارت زیر در ابتدای فایل یا فانکشن مدنظرمون فعال کنیم:&amp;quotuse strict&amp;quotحالا بیایید تستش کنیم:&#039;use strict&#039;;

console.log(hoist); // خروجی: ReferenceError: hoist is not defined
hoist = &#039;Hoisted&#039;;در کدبالا اگر strict-mode فعال نبود متغیر ما به بالای scope خودش  منتقل و hoist میشد، اما موقعی که strict mode فعال هست ما نمیتونیم از  متغیری قبل از تعریف شدنش استفاده کنیم.همچنین به خاطر داشته باشید که strict mode در مرورگرهای مختلف رفتار  مختلفی داره و بهتره که همیشه از کدتون را تست و از درست رفتار کردنش  اطمینان حاصل کنید.let hoistingقبل از اینکه hoisting متغیرهای let در جاوااسکریپت را برسی کنیم این نکته را به خاطر  داشته باشید که کلمه let یک متغیر block-scope ایجاد میکنه و scope این متغیرها برخلاف var مربوط به فانکشنی که در اون تعریف شدن نیست.بیایید با برسی رفتار متغیرهای let شروع کنیم:console.log(hoist); // Output: ReferenceError: hoist is not defined ...
let hoist = &#039;test hoist variable&#039;;مثال بالا را قبلا با کلمه var نوشته بودیم و در اینجاهم انتظار داشتیم تا بجای ReferenceError با مقدار undefined مواجه بشیم. اما در ورژن es6 جاوااسکریپت، متغیرهای ایجاد شده با کلمه let برخلاف متغیرهای var این امکان را به ما نمیدن که از متغیری قبل از تعریف شدنش استفاده کنیم و اصطلاحا hoist نمیشن و درصورت اینکار ما با ReferenceError مواجه خواهیم شد.از اینرو متغیرهای let اطمینان حاصل میکنند تا ابتدا متغیر را تعریف و سپس از اون استفاده کنیم.هرچند که میتونیم به شکل زیر ابتدا متغیر را تعریف و سپس مقدار دهی کنیم و در این صورت دیگه ReferenceError نخواهیم گرفت.let hoist;

console.log(hoist); // Output: undefined
hoist = &#039;test hoist&#039;لذا برای اینکه کد ما به ارور نخوره، نیازه تا ابتدا متغیر را تعریف و  بعد مقداردهی کنیم و یا اینکه همزمان تعریف متغیر و مقدار دهی اونرو انجام  بدیم.const hoistingمتغیرهای const در نسخه es6 اضافه شد و کلمه const متغیری block-scope و اصطلاحا تغییر ناپذیر ایجاد میکنه. یعنی ما نمیتونیم  بصورت مستقیم مقدار اینگونه متغیرهارو با استفاده از عملگر = تغییر بدیم و صرفا زمان هایی که مقدار یک متغیر const برابر با object یا array هست میتونیم مقادیر و محتوای اون object یا array را تغییر بدیم.بیایید یک مثالی از تلاش برای تغییر مقدار یک متغیر const بوسیله عملگر = را ببینیم:const PI = 3.142;

PI = 22/7;

console.log(PI); // خروجی: TypeError: Assignment to constant variable.متغیرهای const برخلاف var و let تغییر ناپذیر و اصطلاحا immutable variables هستند و ما نمیتونیم بصورت مستقیم و با استفاده از عملگر = مقدار جدیدی را به اونها اضافه کنیم و درصورت اینکار با ارور TypeError: Assignment to constant variable مواجه میشیم.حالا بیایید یک مثالی هم از استفاده از یک متغیر const قبل از تعریف شدنش ببینیم:console.log(hoist); // خروجی: ReferenceError: hoist is not defined
const hoist = &#039;hoist test&#039;;const و let در مثال بالا شبیه هم هستند و ما نمیتونیم قبل از تعریف شدن این متغیرها ازشون استفاده کنیم و درصورت اینکار با ارور ReferenceError: hoist is not defined روبرو میشیم. در نتیجه فقط متغیرهای var هستند که hoist میشن و به بالای scope منتقل میشن.همچنین ارور بالا را در مثال زیر هم خواهیم دید و تفاوتی نداره که بخواهید از یک متغیر const در بدنه فانکشن یا هرجای دیگری قبل از تعریف شدنش استفاده کنید:function getCircumference(radius) {
  console.log(circumference)
  circumference = PI*radius*2;
  const PI = 22/7;
}

getCircumference(2) // ReferenceError: circumference is not definedتفاوت دیگر بین متغیرهای const با let و var این هست که ما مجبوریم تا موقع تعریف کردن، اونهارو مقدار دهی هم بکنیم :const PI;
console.log(PI); // خروجی: SyntaxError: Missing initializer in const declarationhoisting functionsفانکشن ها در جاوااسکریپت را میتونیم بطور نسبی به 2 گروه تقسیم کنیم:Function declarationsFunction expressionsحالا بریم تا برسی کنیم که hoisting روی هرکدوم از گروه های بالا به چه صورت رفتار میکنه.Function declarationsاین گروه از فانکشن ها به شکل مثال زیر نوشته میشن و تا بالاترین سطح  scope خودشون منتقل و hoist میشن. از اینرو ما میتونیم قبل از تعریف شدن  این گروه از فانکشن ها ازشون استفاده کنیم.hoisted(); // خروجی: &amp;quothoist test&amp;quot

function hoisted() {
  console.log(&#039;hoist test&#039;);
};Function expressionsاما این گروه از فانکشن ها یعنی Function expressions برخلاف گروه قبلی hoist نمیشن.); //خروجی: &amp;quotTypeError: expression is not a function

var expression = function() {
  console.log(&#039;test hoist&#039;);
};همچنین ترکیب این دو گروه در مثال زیر هم بی اثره و فقط در گروه و مثال اول فانکشن ما hoist و به بالای scope منتقل میشه:); // Ouput: TypeError: expression is not a function

var expression = function hoisting() {
  console.log(&#039;hoist test&#039;);
};قبلتر یادگرفتیم که متغیرهای var به بالای scope منتقل  میشن و ما میتونیم از اونها استفاده کنیم و نکته ایی که خیلی به اون اشاره  کردیم این بود که فقط تعریف متغیر به بالای scope منتقل میشه و نه مقدار  اون! بنابر این در مثال بالا متغیر expression به بالا منتقل شده و مقدار اون undefined هست و زمانیکه ما میخواهیم متغیر expression که مقدارش undefined هست را مثل یک فانکشن صدا بزنیم با ارور TypeError: expression is not a function مواجه میشیم ( این ارور به ما میگه که این متغیر یک فانکشن نیست )ترتیب ها و اولویت بندی هاچند نکته حائز اهمیت درباره تعریف فانکشن ها و متغیرها در جاوااسکریپت وجود داره که باید به خاطر داشته باشید.انتساب مقدار به یک متغیر ( تعریف و مقداردهی همزمان یک متغیر ) بر تعریف یک فانکشن اولویت داره.تعریف یک فانکشن بر تعریف یک متغیر اولویت داره.انتساب مقدار به یک متغیر بر تعریف یک فانکشن اولیت داره و تعریف یک  فانکشن هم به تعریف یک متغیر اولویت داره ( این اولویت بندی ها از نظر  انتقالشون به بالای scope هستش ).بیایید با چند مثال این اولویت بندی هارو بیشتر برسی کنیم:اولویت بیشتر انتساب مقدار به یک متغیر بر تعریف یک فانکشنvar double = 22;

function double(num) {
  return (num*2);
}

console.log(typeof double); // Output: numberاولویت بیشتر تعریف فانکشن نسبت به تعریف متغیرvar double;

function double(num) {
  return (num*2);
}

console.log(typeof double); // Output: functionدر مثال بالا اگر جای تعریف متغیر و فانکشن را عوض کنیم هم خروجی ما فرقی نمیکنه و با مقدار function روبرو میشیم.منبع: https://vaspar.io/blog/hoisting-in-javascript</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Sat, 16 Mar 2024 17:57:26 +0330</pubDate>
            </item>
                    <item>
                <title>برسی آخرین تغییرات در جاوااسکریپت ES14</title>
                <link>https://virgool.io/vaspar/es14-javascript-r3pxfmgun5p1</link>
                <description>با جاوااسکریپت ES14 به متدهای Immutable برای آرایه  ها سلام کنید 😎. یکسری ویژگی های جدید به جاوااسکریپت ES14 یا همان  ECMAScript 2023 اضافه شده که کار با آرایه هارو هم راحت تر و هم جذاب تر  میکنه.از این به بعد متدهای toReversed, toSorted, toSpliced, و with رو داریم و این متدها دیگه خود آرایه اصلی رو دستکاری نمیکنند و بجاش یک  آرایه جدید برامون ایجاد میکنن. علاوه بر اینا، چندتا متد خفن دیگه هم  داریم که الان میخواهیم بریم بطور کامل برسیشون کنیم.ویژگی های جدید در جاوااسکریپت ES14 چیا هستن ؟متد toReversedبا متد toReversed دیگه نیازی به متد قدیمی reverse نداریم. با این متد جدید میتونیم دقیقا همون کار متد قبلی، یعنی برعکس  کردن یک آرایه را انجام بدیم، با این تفاوت که دیگه آرایه اصلیه ما دستکاری  نمیشه و به جاش یک آرایه جدید برامون ساخته میشه.const originalArray = [1, 2, 3, 4, 5];
const newArray = originalArray.toReversed();

console.log(originalArray); // [1, 2, 3, 4, 5] 
console.log(newArray); // [5, 4, 3, 2, 1]متد toSortedمرتب سازی آرایه ها هم با این متد toSorted راحت تر شده و دیگه آرایه اصلی ما دستکاری نمیشه و بجاش یک آرایه جدید برامون ساخته میشه.const numbers = [4, 2, 5, 1, 3]; 
const sortedNumbers = numbers.toSorted((a, b) =&gt; a - b); 

console.log(sortedNumbers); // [1, 2, 3, 4, 5]متد toSplicedمتد toSpliced جایگزینی بهتر و امن تر برای متد قدیمی splice هست. با  این متد میتونیم با خیالی راحت آیتمی را از توی یک آرایه حذف یا جایگزین  کنیم و دیگه نگران دستکاری شدن آرایه اصلیمون هم نباشیم.const numbers = [1, 2, 6, 6, 7];

  const result = numbers.toSpliced(2, 1, 3, 4, 5);
  console.log(result); // [1, 2, 3, 4, 5, 6, 7]متد withمتد with کار تغییر و دستکاری یک آرایه رو برامون بشدت  ساده میکنه. با این متد میتونیم به راحتی index آیتم مدنظر بعلاوه مقدار  جدید رو بهش بدیم و بعد بدونه اینکه آرایه اصلیمون دستکاری بشه، یک آرایه  جدید با ویرایشی که انجام دادیم رو تحویل بگیریم.توی مثال زیر گفتیم آیتمی که ایندکسش 2 هست رو با مقدار 3 جابجا کن:const numbers = [1, 2, 9999, 4];
  const result = numbers.with(2, 3);

  console.log(result); // [1, 2, 3, 4]متد findLastمتد findLast با یک ترتیب معکوس دنبال آیتمی که بهش گفتیم میگرده و اولین آیتمی که با شرط داده شده جور در بیاد را برای ما return میکنه و اگرهم چیزی پیدا نکنه undefined برامون برمیگردونه.const array1 = [5, 12, 50, 100, 44];
  const found = array1.findLast((element) =&gt; element &gt; 45);

  console.log(found); //Output: 100متد findLastIndexاین متد هم دقیقا مثل متد قبل عمل میکنه، یعنی میاد با یک ترتیب معکوس، طبق شرطی که بهش دادیم دنبال ایندکس آیتم مدنظرمون میگرده.const array1 = [5, 12, 50, 100, 44];
const found = array1.findLastIndex((element) =&gt; element &gt; 45);

console.log(found); //Output: 3متد groupByتو این نسخه یعنی جاوااسکریپت ES14 یک متد جذاب به نام groupBy یا همان Object.groupBy اضافه شده که به ما اجازه میده به راحتی آرایه خودمون را دسته بندی کنیم. فرض کنید یک آرایه مثل کد زیر دارید:const products = [
  { name: &amp;quotapples&amp;quot, category: &amp;quotfruits&amp;quot },
  { name: &amp;quotoranges&amp;quot, category: &amp;quotfruits&amp;quot },
  { name: &amp;quotpotatoes&amp;quot, category: &amp;quotvegetables&amp;quot },
];کاری که میخواهیم انجام بدیم اینه که آرایه بالا را طبق پراپرتی category دسته بندی کنیم. یعنی اون آبجکت هایی که مقدار category شون برابر با fruits هست برن توی یک گروه و اونهاییم که category شون برابر vegetables هست هم برن توی یک گروه دیگه.اینکارو به راحتی میتونیم بوسیله متد groupBy به شکل زیر انجام بدیم:const groupByCategory = Object.groupBy(products, (product) =&gt; {
  return product.category;
});

console.log(groupByCategory);
 // خروجی: {
//   &#039;fruits&#039;: [
//     { name: &#039;apples&#039;, category: &#039;fruits&#039; },
//     { name: &#039;oranges&#039;, category: &#039;fruits&#039; },
//   ],
//   &#039;vegetables&#039;: [
//     { name: &#039;potatoes&#039;, category: &#039;vegetables&#039; }
//   ]
// }حالا این متد چطور کار میکنه ؟ متد groupBy دوتا ورودی از  ما میگیره. ورودی اول که آرایه مدنظرمونه و دومین ورودی هم یک کالبک فانکشن  هست. توی ورودی دوم حتما باید نام یک پراپتری که در واقع یک string هست return بشه. دقیقا مثل کد بالا که پراپرتی category را return کردیم.بیایید یک مثال دیگه رو هم باهم ببینیم. تو این مثال میخواهیم یک آرایه ای از اعداد را، طبق زوج و فرد بودن اعداد دسته بندی کنیم:const numbers = [0, 1, 2, 3, 4, 5];

const numbersObj = Object.groupBy(numbers, (num, index) =&gt; {
  return num % 2 === 0 ? &amp;quoteven&amp;quot : &amp;quotodd&amp;quot
});

// خروجی
// {
//   &amp;quoteven&amp;quot: [0, 2, 4],
//   &amp;quotodd&amp;quot: [1, 3, 5]
// }استفاده از Symbols در Weak Collectionsقبل از جاوااسکریپت ES14 نیاز بود تا کلید مجموعه هایی مثل WeakSet و  WeakMap آبجکت باشن. اما تو این بروزرسانی میتونیم حتی از Symbols هم به  عنوان کلید این مجموعه ها استفاده کنیم.const weakMapIds = new WeakMap();
const key = Symbol(&amp;quotuserId&amp;quot);

weakMapIds.set(key, &amp;quot123abc&amp;quot);
console.log(weakMapIds.get(key)); // 123abcHashbang GrammerHashbang Grammer به ما اجازه میده تا به راحتی فایل های جاوااسکریپتی  را از طریق command line اجرا کنیم. دیگه نیازی به ابزار اضافه ای برای  اینکار نداریم و به لطف جاوااسکریپت ES14 میتونیم به راحتی اینکارو انجام  بدیم!#!/usr/bin/env node console.log(&amp;quotJavaScript is greay!&amp;quot);سخن پایانیویژگی های جدیدی که در ECMAScript 2023 یا همان جاوااسکریپت ES14 اضافه  شدن کار مارو با آرایه ها راحت تر میکنند. بطور کلی تمرکز اولیه و اصلی این  بروزرسانی برروی آرایه ها بوده. یکسری متدها اضافه شدن تا دیگه بدون دغدغه  دستکاری شدن آرایه اصلی، بتونیم عملیات مدنظرمون مثل splice یا sort کردن  را انجام بدیم و از طرفی دیگه هم متد groupBy اضافه شد تا فرایند دسته بندی  کردن یک آرایه را برامون راحت تر کنه. راستی اگرم میخواهید بیشتر درباره  جاوااسکریپت و بطور کل فرانت اند یاد بگیرید، توصیه میکنم یک نگاهی هم به دوره آموزش فرانت اند ما  بندازید، ما تو این دوره طبق یک مسیر متفاوت و با پشتوانه یک roadmap خفن فرانت اند را به شما یاد دادیم :)حتما و حتما هم قبل از استفاده از این ویژگی های جدید، مطمعن بشید که  مرورگر یا ورژن NodeJS مدنظرتون این ویژگی را پشتیبانی میکنه یا نه 😀منبع: https://vaspar.io/blog/javascript-es14</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Fri, 15 Mar 2024 19:48:59 +0330</pubDate>
            </item>
                    <item>
                <title>برسی متغیرهای var در جاوااسکریپت</title>
                <link>https://virgool.io/vaspar/javascript-var-variables-lw4zeqvdy3ev</link>
                <description>در این مقاله قصد داریم تا تعریف متغیر با کلمه کلیدی var را زیر ذره بین ببریم و کمی درمورد اون صحبت کنیم، پس در این مقاله باما همراه باشید.کلمه var یک متغیر function-scoped یا globaly-scoped تعریف میکنه و ما  موقع تعریف کردن یک متغیر با کلمه کلیدی var مختار هستیم تا در همان ابتدا  برای اون یک value ( مقدار ) در نظر بگیریم.var x = 1;

if (x === 1) {
  var x = 2;

  console.log(x);
  // خروجی موردانتظار: 2
}

console.log(x);
// خروجی موردانتظار: 2سینتکس تعریف متغیر با کلمه var// کلمه value1 و value2 میتونن هرچیزی باشن، مثل string, number, boolean, array, object

var name1;
var name1 = value1;
var name1 = value1, name2 = value2;
var name1, name2 = value2;
var name1 = value1, name2, /* …, */ nameN = valueN;همچنین امکان Destructuring هم برای متغیرهایی که مقدارشون برابر با یک object هست هم وجود داره، مثل نمونه زیر:var foo = {
  bar:10,
  baz:12,
}

var { bar } = foo; // where foo = { bar:10, baz:12 };
/* بااینکار درواقع ما داریم یک متغیر دیگه به نام bar میسازیم که مقدارش برابر با 10 هستش */متغیرهایی که با کلمه var تعریف میشوند، فارغ از محل تعریف شدنشون،قبل  از هر کدی پردازش خواهند شد، اینرو اصطلاحا hoisting مینامیم و در ادامه  کمی بیشتر درموردش صحبت خواهیم کرد.scope متغیرهایی که با var تعریف میشوند همان زمینه اجرای فعلی اونهاست  یعنی اگر متغیری رو داخل یک function تعریف کنیم، scope اون متغیر محدود به  همان function خواهد بود اما اگر خارج از هرگونه function یک متغیر با  کلمه var تعریف کنیم، scope اون global میشه و در سرتاسر زمینه اجرا یا سند  مربوطه در دسترس هستند. همچنین با تعریف تکراری یک متغیر هم با ارور مواجه  نخواهیم شد و هم اون متغیر value خودش رو از دست نخواهد داد، حتی در حالت  strict mode و فقط زمانی تعریف تکراری متغیرها باعث ایجاد ارور میشن که به  اون متغیر یک مقدار جدیدی را منصوب کنیم.البته به این نکته توجه داشته باشید که scope متغیرهای top-level در  Nodejs Commonjs و ECMAScript همان ماژول مربوطه هست و scope اونها global  نخواهد بود.function foo() {
  var x = 1;
  function bar() {
    var y = 2;
    console.log(x); 
    console.log(y); // 2 (`y` داخل scope هست)
  }
  bar();
  console.log(x); // 1 (`x` داخل scope هست)
  console.log(y); // ReferenceError, `y` در اینجا بهش دسترسی نداریم
}

foo();var hoistingهمانطور که قبلتر گفتیم، متغیرهایی که با کلمه var تعریف  میشوند، فارغ از محل تعریف شدنشون،قبل از هر کدی پردازش خواهند شد و به  بالای scope خودشون خواهند رفت و این به آن معناست که میتوان به این  متغیرها قبل از محل تعریف شدنشون هم دسترسی داشت و به این رفتار اصطلاحا  hoisting میگوییم.به این خاطر بهتر هست که همیشه متغیرهای خودتون رو در بالاترین نقطه  scope مدنظرتون ( که حال یا function هست یا global scope ) تعریف کنید. و  این نکته راهم به خاطر داشته باشید که فقط variable declaration ( تعریف  خود متغیر ) hoist و به بالای scope منتقل میشن و مقدار اونها قبل از منصوب  شدن مقداری، برابر با undefined خواهد بود.function do_something() {
  console.log(bar); // undefined
  var bar = 111;
  console.log(bar); // 111
}چند مثال مختلف از تعریف متغیر با کلمه varتعریف و مقداردهی 2 متغیرvar a = 0,
  b = 0;مقداردهی 2 متغیر با یک مقدار stringvar a = &amp;quotA&amp;quot
var b = a;کد بالا برابره با مثال زیر:var a, b = a = &#039;A&#039;;همچنین حواستون به نظم تعریف کردن متغیرها باشه تا مثل نمونه زیر با مقدار undefined مواجه نشید:var x = y,
  y = &amp;quotA&amp;quot
console.log(x + y); // undefinedAدر اینجا x و y قبل از اینکه توی چرخه کد اجرا بشن تعریف شدن و درنتیجه ReferenceError دریافت نخواهیم کرد اما مقدار دهی اونها چند خط بعد انجام شده و مقدار x در اینجا برابر با undefined هست و چندخط بعد مقدار y برابر با &quot;A&quot; قرار میگیره و درنتیجه هنگام جمع x و y ما خروجی undefinedA را مشاهده میکنیم.مقداردهی  اولیه چند متغیرvar x = 0;
function f() {
  var x = y = 1; // x locally و y globally.
}
f();

console.log(x, y); // 0 1

// درحالت بدون استفاده از strict-mode:
// x طبق انتظارمون global هست;
// y هم خارج از فانکشن ما به بیرون scope خودش درز کرده!همین مثال بالا اما اینبار در حالت strict-mode:&amp;quotuse strict&amp;quot

var x = 0;
function f() {
  var x = y = 1; // ReferenceError در strict mode.
}
f();

console.log(x, y);منبع: کلمه var در جاوااسکریپت چیست - وسپار</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Mon, 04 Mar 2024 19:27:44 +0330</pubDate>
            </item>
                    <item>
                <title>اینترنت چی هست و چطوری کار میکنه ؟</title>
                <link>https://virgool.io/vaspar/how-internet-works-yfc7eq4pvmti</link>
                <description>اینترنت چطور کار میکنه ؟با رشد روز افزون اپلیکیشن ها و زبان ها و ابزارهای مختلف برنامه نویسی، دونستن اینکه اینترنت چیست و چطور کار میکنه برای هر شخصی به خصوص برنامه نویس ها میتونه خیلی مفید باشه. از اینرو  تصمیم گرفتیم تا این مقاله را در کنار ویدئویی با همین موضوع که در دوره آموزش فرانت اند ما وجود داره منتشر کنیم.تو این مقاله قصد داریم تا شمارو با صفر تا صد اینترنت آشنا کنیم، از  مفاهیم پایه گرفته تا مباحث پیشرفته تری مثل نحوه کار کردن اینترنت و  پروتکل ها و غیره. بطور کل شما بعد از خواندن این مقاله به درک عمیقی از  مباحث زیر خواهید رسید:اینترنت چیست ؟اطلاعات چطور در بستر اینترنت منتقل میشن ؟شبکه های مختلف چطور باهم ارتباط برقرار میکنند ؟ارتباط بین packets, routers و reliability چیه ؟HTTP و HTML - چطور صفحات وب برای ما نمایش داده میشن ؟امنیت اطلاعات ارسالی در اینترنت چطور تامین میشه ؟امنیت سایبری و برخی از جرم های رایج در اینترنت چیه ؟خب حالا اینترنت چی هست اصلا ؟سال ها پیش در اوایل دهه 70 میلادی Vint Cerf و Bob Kahn شروع به کار  برروی پروژه ای کردن که امروزه به عنوان اینترنت میشناسیمش و اینترنت  امروزی ما حاصل پروژه ای به نام ARPANET به معنای Advanced Research  Project Agency Network هستش.این پروژه مربوط به وزارت دفاع ایالات متحده بود و شخصی به نام Paul  Baran سعی داشت سیستم ارتباطی بسازه که بتونه از یک حمله اتمی هم حتی جون  سالم بدر ببره. اون با این تفکر سعی داشت پیام هارو به چندین بلوک تقسیم  کنه و در سریعترین زمان ممکن از هر مسیری که ممکن بود به مقصد برسونه.در نهایت این پروژه وزارت دفاع امریکا منجر به یک شبکه بسته در داخل خاک  خود امریکا شد، اما کم کم و با گذشت زمان این شبکه بسته در سراسر دنیا  گسترده شد و امروزه ما اونرو با نام اینترنت میشناسیم، اینترنتی که حاصل  اتصال تعداد زیادی دستگاه در گوشه و کنار این کره خاکی میباشد. اما سوالی  مهم، دستگاه های مختلف در سرتاسر دنیا چطور بهم متصل میشن ؟دستگاه های مختلف چطور بهم وصل میشن و اطلاعات در اینترنت چطور جابجا میشه ؟اطلاعات و داده های موجود در اینترنت از کامپیوتری به کامپیوتر دیگه و  در قالب اطلاعات Binary ارسال میشن و این اطلاعات Binary هم از Bit ها  ساخته شدن. Bit هارو میشه به عنوان جفت های متضادی مثل روشن یا خاموش و بله  یا خیر در نظر گرفت. توصیف تخصصی ترش هم که برای ما برنامه نویس ها همون 0 و 1 ها میشه.ما معمولا از 1 به عنوان بله و از 0 به عنوان خیر استفاده میکنیم. یک  Bit صرفا 2 حالت ممکن داره و به همین خاطر بهشون کد Binary میگیم.8 Bit در کنار هم 1 Byte را تشکیل میدن.هر 1024 Byte هم 1 Kilobyte را تشکیل میدنو هر 1024 Kilobyte هم 1 Megabyte را تشکیل میدهبه عنوان مثال یک آهنگ با حدود 5 الی 6 مگابایت کدگذاری میشه و اصلا هم  تفاوتی نداره که پیام متنی باشه یا عکس یا ویدئو یا آهنگ، همه چیز توی  اینترنت بصورت Bit ارسال و دریافت میشن.حالا به این سوال میرسیم که این اطلاعات چطور از جایی به جای دیگه منتقل میشن ؟تا اینجا متوجه شدیم که اینترنت حاصل اتصال تعداد زیادی کامپیوتر در  سرتاسر دنیا هست و اطلاعات هم فارق از عکس یا متن یا آهنگ بودنشون در قالب  Binary یا همون 0 و 1 ها بین این دستگاه ها ارسال و دریافت میشن.تا اینجاشو فهمیدیم، اما مهمتر از همه اینکه این داده ها چطوری منتقل  میشن ؟ به چه شکل اطلاعات از کامپیوتری در قاره آسیا به یک کامپیوتر دیگه  درقاره آمریکا ارسال میشه ؟پاسخ کوتاه و سریع این سوال میشه سیم ها، کابل ها و امواج رادیویی، اما چطور ؟ بیایید تا بهتون بگمامروزه ما این Bit ها و اطلاعات Binary را از طریق برقی که در سیم ها  جریان داره، پرتوی نوری که در کابل های فیبر نوری بازتاب میشن و امواج  رادیویی که ارسال میشن جابجا میکنیماز کابل های فیبر نوری برای متصل کردن مسیرهای طولانی مانند اتصال یک  قاره به قاره دیگه استفاده میکنیم و دلیلش هم اینه که دارای سرعت بیشتری  هستش نسبت به سیم های معمولی که برق توشون جریان داره. این کابل های فیبر  نوری دارای رشته هایی از جنس شیشه هستن که پرتوهای نور را بازتاب میکنند.اما همچنان برای فواصل کوتاه در خیلی از جاها بدلیل گران قیمت بودن کابل  های فیبر نوری از همان سیم های معمولی استفاده میکنیم. مثل سیم ethernet  که در اکثر منازل پیدا میشه و کاربردش هم اتصال به دستگاه wifi شما هستش.روند کلیه ارسال و جابجایی اطلاعات در اینترنت هم به شکل زیر هستش:اطلاعات باینری از لبتاب یا موبایل پس از ترجمه 0 و 1 ها به فرکانس های  رادیویی، بصورت امواج رادیویی ارسال و توسط wifi که شما بهش متصل هستید  دریافت میشه.پس از دریافت، این اطلاعات Binary از طریق سیم متصل به wifi به isp یا  همان مرکز ارائه دهنده خدمات اینترنتی که سرویس اینترنت را ازش خریداری  کرده ایید منقل میشهو در نهایت هم این اطلاعات از طریق کابل های فیبر نوری به مقصد مدنظر شما منتقل میشهدر انتهای این بخش هم یک نگاهی به برخی مفاهیمی که تا اینجا درموردشون شنیدیم بندازیم:پهنای باند: به حداکثر ظرفیت دستگاه و بیشترین میزان اطلاعاتی که در یک زمان مشخص میتوانند منتقل شوند پهنای باند گفته میشه.Bit Rate: تعداد Bit هایی که میتوان در یک بازه زمانی مشخص منتقل شوند. مثلا 1 میلیون Bit بر ثانیهLatency: مدت زمانیکه طول میکشه یک Bit از جایی به جای دیگه منتقل بشه.برای مطالعه کامل این مقاله اینجا کلیک کنید.</description>
                <category>علی خاکبازان</category>
                <author>علی خاکبازان</author>
                <pubDate>Sun, 03 Mar 2024 01:11:37 +0330</pubDate>
            </item>
            </channel>
</rss>