آموزش جاوا اسکریپت – جلسه ۳۰ – ویژگیهای جدید ES2020

سلام دوستان گرامی. در جلسه قبل (بیست و نهم) با چند سوال تستی جاوا اسکریپت به همراه پاسخ تشریحی آنها در خدمتتان بودیم. سوالات مذکور در زمینه هایی مانند Hoisting متغیرها، حوزه تعریف let و const، کار با آبجکت ها و… بودند. در این جلسه می خواهیم تاریخچه ای از نسخه های اکما اسکریپت را بیان کنیم و ویژگی های جدید اکما اسکریپت 2020 (ES2020) را بیان کنیم. با ما همراه باشید.
ES2020 آخرین ورژن اکما اسکریپت (ECMAScript) است که در سال 2020 میلادی ویژگی های جدیدی به آن اضافه شده است. ES2020 برخلاف ES6 (ورژن ارائه شده در سال 2015 میلادی) تغییرات زیادی ندارد. اما یک سری ویژگی های جدید و کاربردی نسبت به ES6 دارد که در این مقاله قصد داریم ویژگی های ES2020 را به همراه مثال های ساده بیان کنیم. به این ترتیب می توانید براحتی و بسرعت با ویژگی های جدید اکما اسکریپت 2020 آشنا شوید و استفاده از آنها را در مثال های ساده و کاربردی مشاهده کنید.
البته نیاز است قبل از مطالعه این مقاله، یک بینش اولیه و درک صحیح از زبان برنامه نویسی جاوا اسکریپت داشته باشید. بنابراین اگر پیش زمینه ای از javascript ندارید پیشنهاد می کنیم “دوره آموزشی جامع و رایگان جاوا اسکریپت” را مطالعه کنید.
تاریخچه اکما اسکریپت (ECMAscript):
〉 ورژن 1: در تاریخ June 1997 میلادی ارائه شد
〉 ورژن 2: در تاریخ June 1998 میلادی ارائه شد و شامل تغییراتی برای هماهنگ شدن با استانداردهای جهانی ISO/IEC 16262 بود.
〉 ورژن 3: در تاریخ December 1999 ارائه شد و شامل این تغییرات بود: اضافه شدن Regular-Expression و بلاک مدیریت خطای try-catch و فرمت دهی مقادیر عددی و…
〉 ورژن 4: در تاریخ June 2003 معرفی شد اما بنا به دلایلی ارائه نشد. بسیاری از تغییراتی که قرار بود در نسخه 4 عرضه شود به نسخه های بعدی موکول شد.
〉 ورژن 5: در تاریخ December 2009 ارائه شد و شامل این تغییرات بود: اضافه شدن strict mode، اضافه شدن getter/setter و پشتیبانی از JSON و تکمیل شدن مبحث آبجکت ها در جاوا اسکریپت و…
〉 ورژن 5.1: در تاریخ June 2011 ارائه شد و شامل این تغییرات بود: این نسخه از اکما اسکریپت بطور کامل با استانداردهای جهانی ISO/IEC 16262 منطبق شد.
〉 ورژن 6: در تاریخ June 2015 ارائه شد (ES2015) و شامل این تغییرات بود: اضافه شدن ماژول، متغیرهای let, const، توابع arrow، حلقه for..of، کالکشن های جدید SET و MAP، مفهوم promise و…
〉 ورژن 7: در تاریخ June 2016 ارائه شد (ES2016) و شامل این تغییرات بود: اسکوپ بلاک برای متغیرها و توابع، پترن destructuring، عملگر ** برای اعداد، کلمات کلیدی async, await برای برنامه نویسی ناهمگام (asynchronous) و…
〉 ورژن 8: در تاریخ June 2017 ارائه شد (ES2017) و شامل این تغییرات بود: ارائه توابع Object.values و Object.entries و Object.getOwnPropertyDescriptors برای کار با آبجکت ها، بهبود ساختار async/await و…
〉 ورژن 9: در تاریخ June 2018 ارائه شد (ES2018) که شامل این تغییرات بود: اضافه شدن عملگرهای rest, spread، اضافه شدن Promise.prototype.finally و…
〉 ورژن 10: در تاریخ June 2019 ارائه شد (ES2019) که شامل این تغییرات بود: اضافه شدن متدهای Array.prototype.flat و Array.prototype.flatMap، تغییراتی در متدهای Array.sort و Object.fromEntries و…
〉 ورژن 11: در تاریخ June 2020 ارائه شد (ES2020) که شامل این تغییرات بود: Dynamic import، globalThis، nullish coalescing، optional chaining و…
منبع: ویکی پدیا
ویژگی های جدید اکما اسکریپت 2020
- prototype.matchAll
- Dynamic Import
- BigInt
- allSettled
- globalThis
- Nullish Coalescing
- Optional Chaining
- flat() , flatMap()
- Private classes variables
- fromEntries()
Object.fromEntries
متد fromEntries لیست جفت کلید/مقدار یا key/value را به آبجکت تبدیل می کند.
بعنوان مثال:
obj = Object.fromEntries([['a', 0], ['b', 1]]); // { a: 0, b: 1 }
Private classes variables
در حالت پیش فرض، وقتی از propertyکلاس ها در ماژول های مختلف استفاده می کنید، هیچ محدودیتی وجود ندارد. یعنی امکان دسترسی به تمام متدها و صفات کلاس موردنظر را در سایر ماژول ها خواهید داشت.
این قضیه می تواند مشکل ساز باشد. زیرا شاید نخواهیم سایر ماژول ها به فیلدهای کلاس دسترسی داشته باشند. برای رفع این مشکل در ورژن ES2020 قابلیت جدیدی اضافه شد که می توان با درج یک علامت # در ابتدای نام متغیر یا متد آن را به یک فیلد private تبدیل کرد.
بعنوان مثال:
class Booking { #passengers = 2 getPassengers() { console.log(this.#passengers) } } const booking = new Booking() console.log(booking.#passengers) // Error
در کد بالا، با فراخوانی متد greet می توان به مقدار Howdy در کنسول دسترسی داشت. اما نمی توان با دستور greeting.#message بطور مستقیم به متغیر message دسترسی پیدا کرد. زیرا private است.
String.prototype.matchAll:
خروجی متد matchAll() آرایه ای است که با عبارت با قاعده (Regex) تطابق دارد. کد زیر را در این زمینه مشاهده کنید:
const regexp = /t(e)(st(\d?))/g; const str = 'test1test2'; const array = [...str.matchAll(regexp)]; console.log(array[0]); // expected output: Array ["test1", "e", "st1", "1"] console.log(array[1]); // expected output: Array ["test2", "e", "st2", "2"]
Dynamic Import:
دستور import(module) یک ماژول را لود می کند و یک promise برمی گرداند که درون آن آبجکتی است که شامل تمام export ها می باشد. بر خلاف import های ورژن قبل اکما اسکریپت (که در ابتدای ماژول تعریف میشد)، dynamic import می تواند در هر جای کد فراخوانی شود.
بعنوان مثال فرض کنید ماژول math.js بصورت زیر است:
const add = (num1, num2) => num1 + num2; export { add };
و کد فایل index.js نیز به شکل زیر:
const doMath = async (num1, num2) => { if (num1 && num2) { const math = await import('./math.js'); console.log(math.add(5, 10)); }; }; doMath(4, 2);
در این مثال promise بازگشتی از import(‘./math.js’) را awaitکردیم و در متغیر math ذخیره کرده ایم.
برای اطلاعات بیشتر درباره ایمپورت داینامیک، مطالعه “مبحث ماژول ها در جاوا اسکریپت” پیشنهاد می شود.
flat , flatMap
متد flat() به برنامه نویسان جاوا اسکریپت اجازه می دهد تا براحتی چند آرایه چند بعدی (آرایه ای از آرایه ها) را به هم متصل کرده و یک آرایه فلت (تک بعدی) ایجاد کنند. همچنین از آیتم های خالی آرایه صرف نظر می کند.
بعنوان مثال:
const array = ['a', 'b', , ['c', 'd']]; const flattened = array.flat(); console.log(flattened); // => ["a", "b", "c", "d"]
متد flatMap شبیه متد flat کار می کند با این تفاوت که قبل از اتصال آرایه ها (concatenate) متد map را روی آیتم های آرایه اعمال می کند.
بعنوان مثال:
const array = [ 1, 2, 3, 4, 5 ]; const flattened = array.flatMap(x => [x * 3]); console.log(flattened); // => [3, 6, 9, 12, 15]
Optional Chaining
یکی از روش های تعامل با مقادیر falsy استفاده از عملگر optional chaining یعنی ?. می باشد. اگر عملوند مقدار nullish داشته باشد، خطا رخ نمی دهد. به مثال زیر توجه کنید:
let person = {}; console.log(person.profile.name ?? "Anonymous"); // person.profile is not defined console.log(person?.profile?.name ?? "Anonymous"); // no error console.log(person?.profile?.age ?? 18); // no error
بنابراین عملگر optional chaining (?.) این امکان را می دهد تا بدون بروز خطا با مقادیر null و undefined کار کنید.
در تصویر زیر، مثالی دیگر را از optional chaining مشاهده می کنید:
درباره عملگر optional chaining در مقاله “انواع عملگر در جاوا اسکریپپ” بیشتر بخوانید.
Nullish Coalescing
عملگر Nullish Coalescing (??) مقادیر falsy را تشخیص داده و return می کند. به این معنی که اگر عملوند واقع در سمت چپ عملگر ?? یک مقدار falsy باشد، مقدار آن را بر می گرداند. به مثال زیر توجه کنید:
let person = { profile: { name: "", age: 0 } }; console.log(person.profile.name || "Anonymous"); // Anonymous console.log(person.profile.age || 18); // 18
در این مثال، توسط عملگر || (OR) یک شرط گذاشتیم که اگر مثلا person.profile.name برابر یک مقدار falsy بود (مثلا رشته خالی، عدد صفر، null یا undefined)، عملوند سمت راست || برگردد. که در این مثال رشته Anonymous
همین قضیه را در مورد age نیز داریم.
اما اگر بخواهیم کد فوق را با عملگر ?? پیاده سازی کنیم داریم:
console.log(person.profile.name ?? "Anonymous"); // "" console.log(person.profile.age ?? 18); // 0
مشخص است که عملگر nullish coalescing این امکان را به توسعه دهنده می دهد که عملوند سمت چپ را که مقدار falsy دارد را برگرداند. در این مثال name=”” و age=0
در تصویر زیر، مثالی دیگر را از عملگر Nullish Coalescing مشاهده می کنید:
درباره عملگر nullish coalescing در مقاله “عملگرهای جاوا اسکریپت” بیشتر بخوانید.
globalThis
یکی دیگر از ویژگی های جدیدی که در ES2020 (اکما اسکریپت 2020) ارائه شد پشتیبانی از globalThis می باشد. در واقع globalThis امکان پشتیبانی تمام پلتفرم ها را از آبجکت سراسری (global object) فراهم می کند. تا قبل از این، دسترسی به global property در جاوا اسکریپت معمولا مشکلات خودش را داشت. زیرا هر پلتفرم به روش های مختلف به آن دسترسی داشتند. مثلا:
- در سمت کلاینت: با استفاده از this, windows, frame
- در web worker ها: توسط self
- در nodeJS: توسط کلمه global
اما در ES2020 تمامی پلتفرم ها می توانند با استفاده از کلمه کلیدی globalThis می توان به آبجکت گلوبال دسترسی داشت.
Promise.allSettled
وقتی در جاوا اسکریپت با promise ها کار می کنید، به ویژه وقتی این promise ها به یکدیگر مرتبط باشند، اگر بتوانیم وضعیت اجرای هر promiseرا مشاهده کنیم (مثلا کنسول لاگ بگیریم) می تواند مفید باشد.
با متد Promise.allSettled() می توان یک promise جدید ایجاد کرد و promise های موردنظرمان را بعنوان آرگومان به آن پاس دهیم.
const p1 = new Promise((res, rej) => setTimeout(res, 1000)); const p2 = new Promise((res, rej) => setTimeout(rej, 1000)); Promise.allSettled([p1, p2]).then(data => console.log(data));
خروجی کد فوق در کنسول، آرایه ای از آبجکت ها خواهد بود:
[ Object { status: "fulfilled", value: undefined}, Object { status: "rejected", reason: undefined} ]
در آرایه فوق، وضعیت promise های p1 و p2 را مشاهده می کنیم.
BigInt
در ES2020 می توان اعداد بزرگتر از 9007199254740991 (بزرگترین عددی که جاوا اسکریپت تا قبل از es2020 پشتیبانی می کرد) نیز تعریف کرد.
براحتی می توان با افزودن حرف n به انتهای آبجکت BigInt() یک عدد بسیار بزرگ تعریف کرد. به کد زیر توجه کنید:
const bigint = BigInt(Number.MAX_SAFE_INTEGER) + 100n;
بعنوان مثال داریم:
const bigNum = 100000000000000000000000000000n; console.log(bigNum * 2n); // 200000000000000000000000000000n
مقدار bigNum که از نوع BigInt است در 2n ضرب می شود و حاصلش برابر با 200000000000000000000000000000n می شود.
در تصویر زیر می توانید قابلیت های جدید هر یک از نسخه های ES یا EcmaScript را مشاهده کنید:
دیدگاهتان را بنویسید