توسعه فرانت‌اند

JavaScript ES2026: تفکیک استاندارد از پیشنهادهای زبان

اصلاح ادعاهای Pipeline، Record و Tuple و Pattern Matching، معرفی Upsert و JSON.parse source و نمونه Map با تشخیص پشتیبانی و fallback.

1404/10/29 2 دقیقه مطالعه 2,782 بازدید

دیدن یک نمونه از Pipeline Operator در مقاله یا افزونه Babel به معنی استاندارد شدن آن در ES2026 نیست. برای انتخاب قابلیت زبان باید سه چیز جدا شود: متن نسخه منتشرشده، مرحله پیشنهاد و پشتیبانی محیط اجرا. اشتباه گرفتن این‌ها می‌تواند کدی بسازد که در ابزار توسعه پذیرفته می‌شود اما در محیط مخاطب اجرا نمی‌شود. خبر سالانه زبان بهتر است با همین تفکیک خوانده شود.

صفحه رسمی ECMA-262 نسخه هفدهم را با تاریخ ژوئن ۲۰۲۶ معرفی می‌کند. این مقاله در اکتبر ۲۰۲۶ وضعیت را بررسی می‌کند و روی تشخیص ویژگی قطعی از پیشنهاد تمرکز دارد. فهرست پیشنهادهای تمام‌شده بعد از انتشار هم می‌تواند تغییر کند و مواردی برای سال بعد داشته باشد؛ بنابراین نام ES2026 را به همه موارد جدید مخزن نسبت ندهید.

مرحله پیشنهاد چه چیزی می‌گوید؟

فرایند TC39 مرحله‌های بررسی قابلیت را توضیح می‌دهد. یک پیشنهاد اولیه ممکن است در طراحی و حتی هدف تغییر کند. رسیدن به مرحله نهایی با انتشار نسخه سالانه و پشتیبانی همه runtimeها هم‌زمان نیست. در خواندن خبر، مرحله و تاریخ آن را کنار نام قابلیت نگه دارید. عبارتی مانند «به JavaScript اضافه شد» بدون مشخص کردن منظور می‌تواند چند وضعیت متفاوت را پنهان کند.

فهرست Finished Proposals مرحله نهایی و سال انتشار مورد انتظار را جدا نشان می‌دهد. در بررسی اکتبر ۲۰۲۶، مواردی مانند Upsert و JSON.parse source text access با سال ۲۰۲۶ آمده‌اند، در حالی که برخی موارد تازه‌تر برای ۲۰۲۷ فهرست شده‌اند. برای نسبت دادن قابلیت به نسخه، علاوه بر این راهنما، متن همان نسخه و مستندات API را مبنا قرار دهید.

سه ادعای رایج درباره ES2026 درست نیستند

در مخزن Pipeline Operator، وضعیت در زمان این بررسی Stage 2 است. نمونه‌های آزمایشی آن می‌توانند برای بررسی خوانایی مفید باشند، اما آن را قابلیت قطعی ES2026 معرفی نکنید. syntax پیشنهادی هم ممکن است تغییر کند. اگر پروژه از افزونه استفاده می‌کند، این یک قرارداد ابزار ساخت است و باید همراه نسخه و محدودیت آن ثبت شود.

پیشنهاد Record و Tuple در مخزن رسمی withdrawn معرفی شده است. نمونه‌های قدیمی آن را به عنوان API آماده به پروژه منتقل نکنید. کنار گذاشته شدن این پیشنهاد به معنی حذف همه راه‌های کار با داده تغییرناپذیر نیست؛ روش‌های موجود و کتابخانه‌ها قراردادهای خود را دارند. اما شباهت هدف باعث نمی‌شود رفتار آن‌ها معادل یک نوع زبان پیشنهادی تلقی شود.

Pattern Matching نیز در بررسی فعلی Stage 1 است. آن را با destructuring موجود یا شرط‌های معمول زبان یکی ندانید. نام مشترک «الگو» برای چند سازوکار متفاوت استفاده می‌شود. در یک راهنمای کاربردی، syntax آزمایشی باید با برچسب روشن و پیش‌نیاز واقعی ارائه شود؛ برای نمونه آموزشی مستقل، استفاده از قابلیت قابل اجرا و توضیح محدودیت آن انتخاب روشن‌تری است.

Upsert در Map چه مسئله‌ای را حل می‌کند؟

پیشنهاد نهایی Upsert روش‌های getOrInsert و getOrInsertComputed را برای Map و WeakMap شرح می‌دهد. هدف، دریافت مقدار موجود یا وارد کردن مقدار اولیه هنگام نبودن کلید است. نبودن کلید با وجود کلیدی که مقدار undefined دارد متفاوت است. استفاده از عملگرهای پیش‌فرض بدون توجه به این تفاوت می‌تواند رفتار را عوض کند. نام API باید همراه همین قرارداد خوانده شود.

در مرجع getOrInsert در MDN، مقدار موجود جایگزین نمی‌شود. نسخه computed برای ساخت مقدار اولیه از تابع استفاده می‌کند؛ این تفاوت هنگام پرهزینه بودن تولید مقدار مهم است. این API همه عملیات Map را اتمیک یا شبکه‌ای نمی‌کند و مسئله همزمانی چند فرایند یا ذخیره‌سازی پایدار را حل نمی‌کند. دامنه آن به رفتار مجموعه در محیط JavaScript مربوط است.

نمونه کامل با تشخیص پشتیبانی

کد زیر را در map-demo.js ذخیره کنید و با Node.js دارای Map اجرا کنید: فرمان node map-demo.js کافی است و بسته خارجی لازم نیست. اگر getOrInsertComputed وجود داشته باشد از آن استفاده می‌شود؛ در غیر این صورت helper همین نمونه با has و set مسیر جایگزین را انجام می‌دهد. کد، prototype سراسری را تغییر نمی‌دهد و ادعا ندارد تمام جزئیات یک polyfill رسمی را پیاده کرده است.

const articles = [
  { title: 'Navigation', category: 'UX' },
  { title: 'Grid', category: 'CSS' },
  { title: 'Search', category: 'UX' }
];
const groups = new Map();
const hasNative = typeof Map.prototype.getOrInsertComputed === 'function';
function getGroup(map, key) {
  if (hasNative) return map.getOrInsertComputed(key, () => []);
  if (!map.has(key)) map.set(key, []);
  return map.get(key);
}
for (const article of articles) getGroup(groups, article.category).push(article.title);
console.log(hasNative ? 'native getOrInsertComputed' : 'local fallback');
for (const [category, titles] of groups) console.log(category + ': ' + titles.join(', '));

سه عنوان آموزشی بر اساس دسته در Map گروه‌بندی می‌شوند. آرایه تازه فقط زمانی ساخته می‌شود که کلید دسته وجود ندارد؛ عنوان بعدی همان دسته به آرایه موجود افزوده می‌شود. در پایان، دو گروه چاپ می‌شوند و مسیر native یا fallback هم اعلام می‌شود. داده ثابت و محلی است و مثال به API، فایل دیگر یا پایگاه داده وابسته نیست. این نتیجه از ساختار همان سه مورد می‌آید.

JSON.parse و دسترسی به متن منبع

مخزن JSON.parse with source درباره دسترسی به متن منبع در reviver توضیح می‌دهد. این قابلیت برای مواردی که نمایش دقیق یک مقدار primitive اهمیت دارد مفید است؛ برای مثال، تبدیل یک عدد بزرگ پس از از دست رفتن دقت به روش معمول مسئله دارد. در استفاده واقعی، نوع داده مقصد و قرارداد اعتبارسنجی را از ابتدا تعیین کنید و همه اعداد را بی‌دلیل به نوع دیگری تبدیل نکنید.

دریافت متن منبع به معنی معتبر بودن داده کسب‌وکار نیست. یک مقدار می‌تواند JSON معتبر باشد اما از نظر دامنه پروژه نامناسب باشد. اعتبارسنجی طول، محدوده و ساختار همچنان لازم است. داده متنی نیز نباید بدون escape در HTML نمایش داده شود. قابلیت تازه parser یکی از ابزارهای تبدیل است؛ امنیت و معنی داده به قواعد برنامه و محل مصرف آن وابسته می‌مانند.

Syntax، API و پشتیبانی تفاوت دارند

برخی تغییرها syntax تازه‌اند و محیط قدیمی ممکن است پیش از اجرا در parse شکست بخورد. بعضی دیگر method تازه‌اند و می‌توان وجود آن‌ها را در زمان اجرا تشخیص داد. برای انتخاب fallback این تفاوت مهم است. قرار دادن شرط اطراف syntax ناشناخته لزوماً از خطای parse جلوگیری نمی‌کند. ابزار تبدیل هم باید توانایی و قرارداد مشخص داشته باشد؛ تبدیل syntax به معنی فراهم شدن همه APIهای runtime نیست.

در بسته مرورگر، حداقل محیط پشتیبانی‌شده را تعیین کنید. در سرور، نسخه Node.js و سیاست ارتقا مشخص باشد. وجود API در دستگاه توسعه، پشتیبانی مقصد را ثابت نمی‌کند. برای قابلیت تازه، مستندات سازگاری و مسیر fallback را کنار تصمیم نگه دارید. اگر کتابخانه منتشر می‌کنید، محدودیت باید به مصرف‌کننده منتقل شود تا تغییر کوچک شما ناگهان محیط اجرا یا اندازه بسته او را تغییر ندهد.

TypeScript نقش جداگانه دارد

استاندارد شدن قابلیت JavaScript به معنی انتقال عمومی قابلیت‌های type system در TypeScript به runtime نیست. بررسی نوع و رفتار زمان اجرا دو مسئولیت متفاوت دارند. تعریف نوع API در ابزار توسعه هم وجود آن method در محیط نهایی را تضمین نمی‌کند. درباره قراردادهای نوع، راهنمای الگوهای TypeScript مکمل این تفکیک است. انتخاب ابزار باید با مسئله پروژه مرتبط باشد، نه با وعده ایمنی مطلق.

وقتی داده از بیرون می‌آید، annotation نوع جای اعتبارسنجی واقعی را نمی‌گیرد. در استفاده از API تازه نیز، تغییر فایل تنظیمات کامپایل فقط بخشی از آماده‌سازی است. سازگاری، تبدیل و قرارداد داده باید کنار هم دیده شوند. نمونه این مقاله JavaScript معمولی است تا تفاوت میان توان runtime و محیط بررسی نوع روشن بماند. افزودن TypeScript به آن تصمیم جداگانه‌ای درباره پروژه خواهد بود.

ارتقا را با مسئله مشخص انجام دهید

برای هر قابلیت بنویسید چه کد تکراری یا چه ابهامی را کم می‌کند، در کدام محیط اجرا می‌شود و در نبود پشتیبانی چه رخ می‌دهد. افزودن قابلیت تازه فقط برای جدید بودن، هزینه یادگیری و نگهداری ایجاد می‌کند. راهنمای کد تمیز JavaScript درباره خوانایی قراردادها ادامه مفیدی است. یک helper ساده گاهی برای دامنه محدود کافی است، به شرط آنکه محدودیتش روشن باشد.

نام نسخه سالانه را به عنوان نشانه شروع تحقیق استفاده کنید، سپس وضعیت هر قابلیت را جدا بررسی کنید. متن استاندارد، مخزن پیشنهاد و مستندات runtime باید با هم سازگار خوانده شوند. در اکتبر ۲۰۲۶، معرفی Pipeline، Record و Tuple و Pattern Matching به عنوان ویژگی قطعی ES2026 نادرست است. تصمیم قابل اعتماد بر قابلیت نهایی و پشتیبانی واقعی تکیه می‌کند و آزمایش پیشنهادها را با قرارداد روشن ابزار انجام می‌دهد.

واکنش به این مقاله

اشتراک‌گذاری این مقاله:
دیدگاه‌ها 0
۰ / ۲۰۰۰

هنوز دیدگاهی ثبت نشده

اولین نفری باشید که نظر می‌دهد!