5 ویژگی جدید و هیجان انگیز جاوا اسکریپت در سال 2024
در این مقاله، برخی از هیجانانگیزترین و موردانتظارترین آپشن های جاوا اسکریپت را که انتظار داریم که در سال 2024 عرضه شوند، تحلیل خواهیم کرد.
پیشنهادات زیر شانس خوبی برای ورود به نسخه امسال ECMAScript دارند:
به روز رسانی ECMAScript
نسخه جدید JS همیشه سر و صدا ایجاد می کند. از زمان بهروزرسانی ES6، هر سال یک نسخه جدید وجود دارد، و ما انتظار داریم که امسال (ES2024) در ماه ژوئن منتشر شود.
ES6 یک نسخه عظیم بود که شش سال پس از نسخه قبلی خود، ES5 منتشر شد. فروشندگان مرورگر و توسعه دهندگان جاوا اسکریپت غرق در تعداد زیادی ویژگی جدید برای استفاده و یادگیری بودند. از آن زمان، برای جلوگیری از وقوع چنین افت شدید آپشن های جدید، یک چرخه انتشار سالانه وجود دارد.
این چرخه انتشار سالانه شامل پیشنهاد هر ویژگی جدید است، که سپس مورد بحث، ارزیابی و سپس توسط یک کمیته قبل از اضافه شدن به زبان مورد نظر قرار می گیرد. این فرآیند همچنین به مرورگرها اجازه میدهد تا پیشنهادات را قبل از اضافه شدن رسمی به زبان پیادهسازی کنند، که ممکن است به رفع مشکلات پیادهسازی کمک کند.
همانطور که گفته شد، ویژگی های جدید جاوا اسکریپت (یا ECMAScript) توسط کمیته فنی 39 (TC39) تصمیم گیری می شود. TC39 متشکل از نمایندگانی از تمام فروشندگان عمده مرورگرها و همچنین کارشناسان جاوا اسکریپت است. آنها مرتباً گرد هم می آیند تا درباره ویژگی های جدید زبان و نحوه پیاده سازی آنها بحث کنند. آپشن های جدید بهعنوان پیشنهاد (طراحی شده توسط هر کسی) مطرح میشوند و اعضای کمیته در مورد اینکه آیا هر پیشنهاد میتواند به مرحله بعد حرکت کند یا خیر، رأی میدهند. برای هر پیشنهاد 4 مرحله وجود دارد. زمانی که یک پیشنهاد به مرحله 4 برسد، پیش بینی می شود در نسخه بعدی ES گنجانده شود.
بخش مهمی از مشخصات ES این است که باید با عقب سازگار باشد. این بدان معنی است که هیچ ویژگی جدیدی نمی تواند با تغییر نحوه عملکرد نسخه های قبلی ES اینترنت را از بین ببرد . پس آنها نمیتوانند نحوه کار روشهای موجود را تغییر دهند، فقط میتوانند روشهای جدیدی را اضافه کنند، زیرا هر وبسایتی که با یک روش بالقوه از قبل وجود داشته باشد، در معرض خطر شکسته شدن است.
فهرست کامل همه پیشنهادات فعلی را می توانید در اینجا مشاهده کنید.
زمانی
در نظرسنجی State of JS 2022، سومین پاسخ متداول به "چه چیزی را در حال حاضر از جاوا اسکریپت گم میکنید؟" مدیریت بهتر تاریخ بود.
این منجر به پیشنهاد Temporal
شده است که یک شی استاندارد جهانی را برای جایگزینی شیء Date
ارائه می دهد و تعدادی از مشکلاتی را که در طول سال ها هنگام کار با تاریخ ها در جاوا اسکریپت باعث دردسر زیادی برای توسعه دهندگان شده است، برطرف می کند.
کار با تاریخ در جاوا اسکریپت تقریباً همیشه یک کار وحشتناک است. باید با ناهماهنگی های کوچک اما آزاردهنده کنار بیایید، مانند دیوانگی ماه ها که شاخص صفر هستند اما روزهای ماه که از 1 شروع می شوند.
دشواری تاریخ ها باعث شده است که کتابخانه های محبوبی مانند Moment، Day.JS و date-fns برای رفع مشکلات ظاهر شوند. با این حال، Temporal
API قصد دارد تمام مشکلات را به صورت بومی برطرف کند.
Temporal
از چندین منطقه زمانی و تقویمهای غیر گرگوری پشتیبانی میکند و یک API ساده برای استفاده ارائه میکند که تجزیه تاریخها را از رشتهها بسیار آسانتر میکند. علاوه بر این، تمام اشیاء Temporal
تغییرناپذیر خواهند بود، که به جلوگیری از هر گونه اشکال تصادفی تغییر تاریخ کمک می کند.
بیایید به چند نمونه از مفیدترین روش های ارائه شده توسط Temporal
API نگاه کنیم.
Temporal.Now.Instant()
Temporal.Now.Instant()
یک شیء DateTime را به نزدیکترین نانوثانیه برمی گرداند. می توانید تاریخ های خاصی را با استفاده از روش from
تعیین کنید:
const olympics = Temporal . Instant . from ( '2024-07-26T20:24:00+01:00' ) ;
این یک شی DateTime ایجاد می کند که نشان دهنده شروع بازی های المپیک پاریس در اواخر امسال در ساعت 20:24 در 26 جولای 2024 (UTC) است.
PlainDate()
این به شما امکان می دهد فقط یک تاریخ بدون زمان ایجاد کنید:
new Temporal . PlainDate ( 2024 , 7 , 26 ) ; Temporal . PlainDate . from ( '2024-07-26' ) ;
PlainTime()
به عنوان مکمل PlainDate()
، می توانیم از این برای ایجاد یک زمان بدون تاریخ با استفاده از .PlainTime()
استفاده کنیم:
new Temporal . PlainTime ( 20 , 24 , 0 ) ; Temporal . PlainTime . from ( '20:24:00' ) ;
PlainMonthDay()
PlainMonthDay()
مشابه PlainDate
است، اما فقط ماه و روز را بدون اطلاعات سال برمی گرداند (مفید برای تاریخ هایی که هر سال در یک روز تکرار می شوند، مانند روز کریسمس و روز ولنتاین):
const valentinesDay = Temporal . PlainMonthDay . from ( { month : 2 , day : 14 } ) ;
PlainYearMonth()
به طور مشابه، PlainYearMonth
نیز وجود دارد که فقط سال و ماه را برمیگرداند (برای نمایش یک ماه کامل از یک سال مفید است):
const march = Temporal . PlainYearMonth . from ( { month : 3 , year : 2024 } ) ;
محاسبات
تعدادی محاسبات وجود دارد که می توان با اشیاء Temporal انجام داد. شما می توانید واحدهای مختلف زمان را به یک شی تاریخ اضافه و کم کنید:
const today = Temporal . Now . plainDateISO ( ) ; const lastWeek = today . subtract ( { days : 7 } ) ; const nextWeek = today . add ( { days : 7 } ) ;
روشهای until
و since
به شما این امکان را میدهند که بفهمید تا یک تاریخ خاص یا از زمان وقوع آن تاریخ چقدر زمان باقی مانده است. به عنوان مثال، کد زیر به شما می گوید چند روز تا المپیک پاریس باقی مانده است:
olympics . until ( ) . days valentinesDay . since ( ) . hours
این روشها یک شی Temporal.Duration
را برمیگردانند که میتواند برای اندازهگیری مقدار زمانی که دارای واحدهای مختلف و گزینههای گردآوری متعددی است، استفاده شود.
میتوانید سال، ماه و روز را از یک شی Date استخراج کنید و ساعتها، دقیقهها، ثانیهها، میلیثانیهها، میکروثانیهها و نانوثانیهها یک شی Time را تشکیل میدهند (میکرو ثانیه و نانوثانیه در شی DateTime فعلی موجود نیستند). مثلا:
olympics . hour ; << 20
همچنین داراییهای دیگری مانند dayOfWeek
( 1
برای دوشنبه و 7
برای یکشنبه)، daysInMonth
(بسته به ماه 28
، 29
، 30
یا 31
برمیگرداند) و daysinYear
(بسته به سال کبیسه 365
یا 366
را برمیگرداند) وجود دارد.
اشیاء تاریخ Temporal
دارای روش compare
نیز خواهند بود که می توان از آن برای مرتب کردن تاریخ ها با استفاده از الگوریتم های مرتب سازی مختلف استفاده کرد.
Temporal در حال حاضر یک پیشنهاد مرحله 3 است که در مرحله پیاده سازی توسط فروشندگان مرورگر است، پس به نظر می رسد که زمان آن فرا رسیده است ( جناس در نظر گرفته شده). شما می توانید مستندات کامل را اینجا ببینید. همچنین یک کتاب آشپزی مفید از موارد استفاده در اینجا وجود دارد. وقتی با Intl.DateTimeFormat API جفت میشوید، میتوانید دستکاری تاریخ بسیار خوبی را انجام دهید.
اپراتور لوله
در نظرسنجی State of JS 2022، ششمین پاسخ برتر به "چه چیزی در جاوا اسکریپت گم شده است؟" اپراتور لوله بود.
می توانید پیشنهاد اپراتور لوله را اینجا ببینید.
اپراتور لوله یک ویژگی استاندارد در زبان های تابعی است که به شما امکان می دهد یک مقدار را از یک تابع به تابع دیگر "pipe" کنید، با خروجی تابع قبلی به عنوان ورودی به تابع بعدی (به روشی مشابه که Fetch API ارسال می کند). هر داده ای که از یک وعده به وعده دیگر برمی گرداند).
به عنوان مثال، فرض کنید میخواهیم سه تابع را به صورت متوالی در یک رشته اعمال کنیم:
رشته "Listen up!" را به هم متصل کنید. به ابتدای رشته اصلی
سه علامت تعجب را در انتهای رشته به هم بچسبانید.
تمام متن را با حروف بزرگ بنویسید.
این سه تابع را می توان به صورت زیر نوشت:
const exclaim = string => string + "!!!" const listen = string => "Listen up! " + string const uppercase = string => string . toUpperCase ( )
این سه تابع را می توان با تودرتو کردن همه آنها در کنار هم به صورت زیر اعمال کرد:
const text = "Hello World" uppercase ( exclaim ( listen ( text ) ) ) << "LISTEN UP! HELLO WORLD!!!"
اما تودرتوی عمیق فراخوانیهای چند تابع مانند این میتواند خیلی سریع به هم ریخته شود، بهویژه از آنجایی که مقدار ( text
) که بهعنوان آرگومان ارسال میشود، عمیقاً درون عبارت جاسازی میشود و شناسایی آن را دشوار میکند.
مشکل دیگر تودرتوی توابع این است که ترتیب اعمال توابع به صورت پشت سر هم به جلو است، به این صورت که ابتدا بیشترین توابع داخلی اعمال می شوند. پس ، در این حالت، listen
به مقدار اصلی text
اعمال میشود، سپس exclaim
، سپس تابع بیرونی، uppercase
، در آخر اعمال میشود. به خصوص برای توابع بزرگ و پیچیده، پیگیری این امر سخت و غیرمعمول می شود.
یک جایگزین این است که از تابع زنجیره ای مانند زیر استفاده کنید:
const text = "Hello World" text . listen ( ) . exclaim ( ) . uppercase ( )
این بسیاری از مشکلات توابع تو در تو را حل می کند. آرگومان ارسال شده در ابتدا است و هر تابع به ترتیبی که اعمال میشود ظاهر میشود، پس ابتدا listen()
اعمال میشود، سپس exclaim()
و سپس uppercase()
.
متأسفانه، این مثال کار نخواهد کرد، زیرا توابع listen
، exclaim
و uppercase
متدهای کلاس String
نیستند. آنها را می توان با وصله کردن کلاس String
توسط میمون ها اضافه کرد، اما این به طور کلی به عنوان یک تکنیک نادیده گرفته می شود.
این بدان معنی است که، اگرچه زنجیرهسازی بسیار بهتر از تودرتوی توابع به نظر میرسد، اما واقعاً میتوان از آن با توابع داخلی استفاده کرد (همانطور که اغلب با روشهای آرایه انجام میشود).
لوله کشی سهولت استفاده از زنجیر را با قابلیت استفاده از آن با هر عملکردی ترکیب می کند. تحت پیشنهاد فعلی، مثال بالا به این صورت نوشته می شود:
text | > listen ( % ) | > exclaim ( % ) | > uppercase ( % )
نشانه %
یک مکان نگهدار است که برای نشان دادن مقدار خروجی تابع قبلی استفاده میشود، اگرچه به احتمال زیاد کاراکتر %
با کاراکتر دیگری در نسخه رسمی جایگزین میشود. این اجازه می دهد تا توابعی که بیش از یک آرگومان را می پذیرند در طول خط لوله استفاده شوند.
لوله کشی سهولت زنجیر زدن را ترکیب می کند اما می تواند با هر عملکرد سفارشی که نوشته اید استفاده شود. تنها شرط این است که باید اطمینان حاصل کنید که نوع خروجی یک تابع با نوع ورودی تابع بعدی در زنجیره مطابقت دارد.
Piping با توابع Curried که فقط یک آرگومان منفرد را می پذیرند که از مقدار بازگشتی هر تابع قبلی لوله شده است، بهترین کار را دارد. این برنامهنویسی عملکردی را بسیار آسانتر میکند، زیرا توابع کوچک و بلوکهای ساختمانی را میتوان به هم متصل کرد تا توابع ترکیبی پیچیدهتری ایجاد کنند. همچنین اجرای جزئی را آسان تر می کند.
با وجود محبوبیت، اپراتور لوله تلاش کرده است تا فراتر از مرحله 2 روند حرکت کند. این به دلیل اختلاف نظر در مورد نحوه بیان نماد و نگرانی در مورد عملکرد حافظه و نحوه عملکرد آن با await
است. به نظر می رسد که کمیته به آرامی در حال دستیابی به نوعی توافق است، پس امیدواریم که اپراتور لوله بتواند به سرعت مراحل را طی کند و امسال ظاهر شود.
خوشبختانه اپراتور خط لوله از نسخه 7.15 در بابل پیاده سازی شده است.
ما شخصاً دوست داریم که اپراتور لوله در سال جاری پیاده سازی و عرضه شود، زیرا واقعاً به بهبود اعتبار جاوا اسکریپت به عنوان یک زبان برنامه نویسی کاربردی جدی کمک می کند.
رکوردها و تاپل ها
هدف Record and Tuple ارائه ساختارهای داده تغییرناپذیر به جاوا اسکریپت است.
تاپل ها شبیه به آرایه ها هستند - فهرست مرتب شده ای از مقادیر - اما عمیقا تغییر ناپذیر هستند. این بدان معناست که هر مقدار در یک تاپل یا باید یک مقدار اولیه باشد یا یک رکورد یا تاپل دیگر (نه آرایه یا اشیاء، زیرا در جاوا اسکریپت قابل تغییر هستند).
یک تاپل به روشی مشابه آرایه به معنای واقعی کلمه ایجاد می شود، اما با نماد هش پیشرو ( #
) در جلو:
const heroes = # [ "Batman" , "Superman" , "Wonder Woman" ]
هنگامی که این ایجاد شد، هیچ مقدار دیگری را نمی توان اضافه کرد و هیچ مقداری را نمی توان حذف کرد. مقادیر نیز قابل تغییر نیستند.
رکوردها شبیه به اشیا هستند - مجموعه ای از جفت های کلید-مقدار - اما آنها همچنین عمیقا تغییر ناپذیر هستند. آنها به روشی مشابه یک شی ایجاد می شوند - اما مانند تاپل ها، با یک هش اصلی شروع می شوند:
const traitors = # { diane : false , paul : true , zac : false , harry : true }
رکوردها همچنان از نماد نقطه برای دسترسی به ویژگی ها و روش ها استفاده می کنند:
traitors . paul << true
و نماد براکت مربعی که آرایه ها استفاده می کنند نیز می تواند برای تاپل ها استفاده شود:
heroes [ 1 ] << "Superman"
اما از آنجایی که آنها تغییر ناپذیر هستند، نمی توانید هیچ یک از ویژگی ها را به روز کنید:
traitors . paul = false << Error heroes [ 1 ] = "Supergirl" << Error
تغییرناپذیری تاپل ها و رکوردها به این معنی است که شما می توانید به راحتی آنها را با استفاده از عملگر ===
مقایسه کنید:
heroes === # [ "Batman" , "Superman" , "Wonder Woman" ] ; << true
نکته ای که باید به آن توجه داشت این است که ترتیب ویژگی ها هنگام در نظر گرفتن برابری رکوردها مهم نیست:
traitors === # { ross : false , zac : false , paul : true , harry : true } ; << true
با این حال، ترتیب برای تاپل ها مهم است ، زیرا آنها فهرستی مرتب شده از داده ها هستند:
heroes === # [ "Wonder Woman" , "Batman" , "Superman" ] ; << false
این صفحه دارای یک آموزش مفید با زمین بازی زنده است تا بتوانید به نحوه عملکرد رکوردها و تاپل ها عادت کنید.
پرچم RegExp /v
عبارات منظم از نسخه 3 در جاوا اسکریپت گنجانده شده اند و از آن زمان تاکنون پیشرفت های زیادی صورت گرفته است (مانند پشتیبانی یونیکد با استفاده از پرچم u
در ES2015). هدف پیشنهاد پرچم v
انجام هر کاری است که پرچم u
انجام می دهد، اما برخی از مزایای اضافی را اضافه می کند که در مثال های زیر به آنها نگاه خواهیم کرد.
به سادگی، اجرای پرچم v
مستلزم گفت ن یک /v
به انتهای عبارت منظم شما است.
به عنوان مثال، کد زیر را می توان برای آزمایش اینکه آیا یک کاراکتر یک ایموجی است استفاده کرد:
const isEmoji = / ^ \p { RGI_Emoji } $ / v ; isEmoji . test ( "💚" ) ; << true isEmoji . test ( "🐨" ) ; << true
این از الگوی RGI_Emoji
برای شناسایی ایموجی ها استفاده می کند.
پرچم v
همچنین به شما این امکان را می دهد که از نماد مجموعه در عبارات منظم خود استفاده کنید. برای مثال، می توانید با استفاده از عملگر --
یک الگو را از الگوی دیگر کم کنید. کد زیر را می توان برای حذف هر قلب عشق از مجموعه ایموجی ها استفاده کرد:
const isNotHeartEmoji = / ^ [ \p { RGI_Emoji_Tag_Sequence } -- \q { 💜💚♥️💙🖤💛🧡🤍🤎 } ] $ / v ; isNotHeartEmoji . test ( "💚" ) ; << false isNotHeartEmoji . test ( "🐨" ) ; << true
با استفاده از &&
می توانید محل تلاقی دو الگو را پیدا کنید. به عنوان مثال، کد زیر محل تقاطع نمادها و حروف یونانی را پیدا می کند:
const GreekLetters = / [ \p { Script_Extensions = Greek } && \p { Letter } ] / v ; GreekLetters . test ( 'π' ) ; << true GreekLetters . test ( '𐆊' ) ; << false
پرچم v
همچنین برخی از مشکلاتی را که پرچم u
در مورد عدم حساسیت حروف بزرگ داشت برطرف می کند، و آن را به گزینه بسیار بهتری برای استفاده در تقریباً همه موارد تبدیل می کند.
پرچم v
برای عبارات منظم در طول سال 2023 به مرحله 4 رسید و در تمام مرورگرهای اصلی پیاده سازی شده است، پس پیش بینی می شود که به طور کامل بخشی از مشخصات ES2024 باشد.
دکوراتورها
هدف دکوراتور استفاده از دکوراتورها برای گسترش کلاس های جاوا اسکریپت به صورت بومی است.
دکوراتورها در بسیاری از زبان های شی گرا مانند پایتون رایج هستند و قبلاً در TypeScript گنجانده شده اند. آنها یک انتزاع فرابرنامهنویسی استاندارد هستند که به شما امکان میدهند بدون تغییر ساختار یک تابع یا کلاس، عملکرد اضافی را اضافه کنید. به عنوان مثال، ممکن است بخواهید مقداری اعتبار سنجی اضافی به یک روش اضافه کنید، و می توانید این کار را با ایجاد یک دکوراتور اعتبار سنجی که داده های وارد شده در یک فرم را تحلیل می کند، انجام دهید.
در حالی که جاوا اسکریپت به شما امکان می دهد از توابع برای پیاده سازی این الگوی طراحی استفاده کنید، اکثر برنامه نویسان شی گرا روش ساده تر و بومی را برای دستیابی به این امر ترجیح می دهند تا زندگی را بسیار آسان تر کنند.
این پیشنهاد مقداری قند نحوی اضافه میکند تا به شما امکان میدهد به راحتی یک دکوراتور را در یک کلاس پیادهسازی کنید، بدون اینکه نیازی به اتصال this
به کلاس باشید. راه بسیار تمیزتری برای گسترش عناصر کلاس، مانند فیلدهای کلاس، متدهای کلاس، یا دسترسی های کلاس ارائه می دهد، و حتی می تواند برای کل کلاس اعمال شود.
دکوراتورها با پیشوند نماد @
مشخص می شوند و همیشه بلافاصله قبل از کدی که "تزیین می کنند" قرار می گیرند.
به عنوان مثال، دکوراتور کلاس بلافاصله قبل از تعریف کلاس می آید. در مثال زیر، دکوراتور validation
برای کل کلاس FormComponent
اعمال میشود:
@validation class FormComponent { } function validation ( target ) { }
دکوراتور متد کلاسی بلافاصله قبل از روشی که تزئین می کند می آید. در مثال زیر، دکوراتور validation
برای روش submit
اعمال شده است:
class FormComponent { @validation submit ( data ) { } } function validation ( target ) { }
تعاریف تابع دکوراتور دو پارامتر را می پذیرد: یک مقدار و زمینه. آرگومان value به مقداری که تزئین میشود (مثلاً یک متد کلاس) اشاره دارد و متن حاوی ابردادههایی درباره مقدار است، مانند اینکه آیا یک تابع است یا نه، نام آن، و اگر ثابت یا خصوصی است. شما همچنین می توانید یک تابع اولیه را به زمینه اضافه کنید که در زمان نمونه سازی یک کلاس اجرا می شود.
پروپوزال دکوراتور در حال حاضر در مرحله 3 است و در بابل اجرا شده است، پس می توانید آن را امتحان کنید.
نتیجه
خب چی فکر می کنی؟ دوست دارید امسال چه چیزی به مشخصات اضافه شود؟ همه این ویژگیها به جاوا اسکریپت گفت ه میشوند، پس در سال جاری به آن دست خواهند یافت!
ارسال نظر