ابتكارات ES2020 التي أحبها حقًا

تم تطوير JavaScript بسرعة كبيرة في السنوات الأخيرة. وينطبق هذا بشكل خاص على الفترة التالية لإصدار معيار ES6 في عام 2015. منذ ذلك الحين ، ظهرت الكثير من الميزات الرائعة في اللغة. تم اقتراح الكثير من الميزات الجديدة لإدراجها في معيار ES2020. تم تشكيل قائمة نهائية بالميزات بالفعل ، ويمكن توقع ظهورها في المعيار بعد الموافقة عليها. هذه أخبار جيدة لجميع عشاق JS. يقول كاتب المقال ، الذي ننشر ترجمته اليوم ، أنه من بين هذه الفرص هناك فرص يسعدها بشكل خاص. قبل ظهورها ، كان من الصعب عليه كتابة رمز في المواقف التي تكون فيها قابلة للتطبيق. وفقا له ، إذا ظهروا في اللغة في وقت سابق ، لكانوا قد وفروا له الكثير من الوقت والجهد.





سلاسل اختيارية


تعتبر Chaining الاختيارية ، بالنسبة لي شخصيًا ، واحدة من أكثر الميزات إثارة لمعيار ES2020. لقد كتبت العديد من البرامج التي ستكون فيها هذه الميزة مفيدة للغاية. 

تسمح لك السلاسل الاختيارية بتنظيم الوصول الآمن إلى الخصائص المضمّنة بعمق للكائنات دون الحاجة إلى التحقق من وجود كل منها. ألق نظرة على كيفية عمل هذه الميزة.

أولاً ، انظر إلى الرمز الذي كان يجب كتابته قبل ظهور السلاسل الاختيارية.

▍ رمز حتى تظهر سلاسل اختيارية


const user = {
   firstName:"Joseph",
   lastName:"Kuruvilla",
   age:38,
   address:{
      number:"239",
      street:"Ludwig Lane",
      city:"Chennai",
      zip:"600028",
   prop1:{
    prop2:{
     prop3:{
      prop4:{
       value:'sample'
      }
     }
    }
   }
   }
}
if(user && user.address){
 console.log(user.address.zip);
 //600028
}
if(user && user.address && user.address.prop1 && user.address.prop1.prop2 && user.address.prop1.prop2.prop3 && user.address.prop1.prop2.prop3.prop4){
 console.log(user.address.prop1.prop2.prop3.prop4.value);
 //sample
}
//    
console.log(user.address.prop102.po);
//Error

كما ترى ، من أجل تجنب حدوث الأخطاء ، يبدو Cannot read property 'po' of undefinedأنه من الضروري ، في كل مستوى من مستويات التداخل ، التحقق من الخصائص لوجودها. مع زيادة عمق تداخل الكيانات ، يزداد أيضًا عدد الخصائص المحددة. هذا يعني أنه يجب على المبرمج نفسه كتابة التعليمات البرمجية التي تحميها من الخصائص التي ، عند الوصول إليها ، يمكن أن تصل إلى قيم nullأو undefined.

▍ كود بعد ظهور سلاسل اختيارية


كتابة التعليمات البرمجية مثل تلك التي استعرضناها للتو جعلت الأمر أسهل بكثير مع ظهور السلاسل الاختيارية. لتنظيم العمل الآمن مع خصائص الأشياء المتضمنة بعمق ، يكفي استخدام عامل التشغيل ?.. يحفظنا من الحاجة إلى التحقق من القيم بشكل مستقل nullو undefined.

إليك ما يبدو عليه:

const user = {
   firstName:"Joseph",
   lastName:"Kuruvilla",
   age:38,
   address:{
      number:"239",
      street:"Ludwig Lane",
      city:"Chennai",
      zip:"600028",
   prop1:{
    prop2:{
     prop3:{
      prop4:{
       value:'sample'
      }
     }
    }
   }
   }
}
console.log(user?.address?.zip);
//600028
console.log(user?.address?.prop1?.prop2?.prop3?.prop4?.value);
//sample
//    
console.log(user?.address?.prop102?.po);
//undefined

حسنًا ، أليس كذلك؟ بفضل هذا الابتكار ، جعل ES2020 من الممكن التخلص من عدد كبير من أسطر التعليمات البرمجية.

التحقق من القيم الفارغة وغير المحددة فقط


التحقق من القيم فقط على nullو undefined(Nullish Coalescing) هي واحدة من تلك الميزات التي أسعدتني حقًا حتى عندما كانت الاحتمالات في مرحلة الاقتراح. غالبًا ما صادفت الحاجة إلى كتابة وظائف متخصصة لإجراء الفحوصات المناسبة.

من المعروف أن جافا سكريبت لها معاني "خاطئة" و "حقيقية". الآن يمكننا القول أنه تمت إضافة قيم "صفر" إليهم. هذه القيم تشمل nullو undefined. باستخدام مصطلحات JavaScript "خاطئة" ، تكون السلاسل الفارغة ، والرقم 0 ، والقيم undefined، null، false، NaN. هذا ، على سبيل المثال ، تعبير معين للتحقق من قيمة "الباطل" سيعمل على سلسلة فارغة ، وعلى القيمةundefined، وأكثر من ذلك بكثير على ماذا. والتعبير للتحقق من قيمة ما إذا كان "صفر" سيعود trueفقط لـ nullو undefined. ربما لا تبدو هذه الفرصة رائعة بالنسبة لك شخصيًا ، ولكنها في الواقع مهمة جدًا جدًا.

دعونا نلقي نظرة على بعض الأمثلة.

code الكود حتى القدرة على التحقق من القيم فقط على null و غير المعرفة


كنت أعمل مؤخرًا على مشروع كنت بحاجة فيه إلى تنفيذ وظيفة التبديل بين السمات الفاتحة والداكنة. في نفس الوقت ، كان علي التحقق من حالة عنصر التحكم ، ومعرفة ما إذا كان يتوافق مع قيمة trueأو false. إذا لم يقم المستخدم بتعيين أي قيمة ، يجب أن تكون متساوية افتراضيًا true. إليك كيفية حل هذه المشكلة قبل إمكانية التحقق من القيم فقط على nullو undefined:

const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
  if (darkModePreference || darkModePreference === false) {
    return darkModePreference
  }
  return true
}
getUserDarkModePreference(darkModePreference1) 
// true
getUserDarkModePreference(darkModePreference2) 
// false
getUserDarkModePreference(darkModePreference3) 
// true
getUserDarkModePreference(darkModePreference4) 
// true

▍ كود بعد امكانية التحقق من القيم فقط على قيمة فارغة وغير محددة


مرة واحدة وقد ظهرت هذه الميزة في اللغة لفحص nullو undefinedمشغل كافية ??. في هذه الحالة ، يمكنك الاستغناء عن عامل شرطي if:

const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
  return darkModePreference ?? true;
}
getUserDarkModePreference(darkModePreference1) 
// true
getUserDarkModePreference(darkModePreference2) 
// false
getUserDarkModePreference(darkModePreference3) 
// true
getUserDarkModePreference(darkModePreference4) 
// true

هنا يحدث ما يلي: إذا كان المتغير darkModePreferenceيحتوي على قيمة "صفر" ، فسيتم إرجاع القيمة true. هذا يجعل من السهل كتابة التعليمات البرمجية ، وهو مضغوط وسهل الفهم.

الواردات الديناميكية


تساهم عمليات الاستيراد الديناميكية في أداء تطبيق أكثر كفاءة. تسمح لك هذه التقنية باستيراد ملفات JS ديناميكيًا ، على شكل وحدات ، دون تضمين أدوات إضافية. علاوة على ذلك ، إذا لم تكن الوحدة مطلوبة ، فلا يتم استيرادها. قبل ES2020 ، تم استيراد الوحدات بغض النظر عما إذا كانت مستخدمة من قبل التطبيق أم لا.

على سبيل المثال ، لنفترض أننا بحاجة إلى تنفيذ وظيفة تحميل ملف معين بتنسيق PDF.

فكر كالعادة في الخيارات القديمة والجديدة لحل هذه المشكلة.

▍ كود قبل دعم الاستيراد الديناميكي


استنادًا إلى الوضع الحقيقي ، يمكننا أن نتوقع أن القدرة على تنزيل المواد بتنسيق PDF لن يستخدمها جميع زوار الصفحة. لكن الوحدة المقابلة ، على أي حال ، يجب استيرادها إلى الشفرة. وهذا يعني أنه سيتم تحميل الوحدة ، سواء كانت هناك حاجة إليها أم لا ، عند تحميل الصفحة.

import { exportAsPdf } from './export-as-pdf.js'
const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', exportAsPdf);

هذا يخلق حمولة إضافية على النظام ، والتي يمكن تسهيلها باستخدام التحميل البطيء للوحدات. يمكن القيام بذلك باستخدام تقنية فصل الكود ، والتي تتوفر في حزمة الويب أو في لوادر الوحدة النمطية الأخرى (ويعني استخدامها في حد ذاته إنفاق قدر معين من موارد النظام).

ولكن الآن ، بفضل ES2020 ، لدينا طريقة قياسية لتحميل الوحدات ديناميكيًا ، مما يسمح لنا بالاستغناء عن الحزم.

▍ رمز بعد ظهور الدعم لعمليات الاستيراد الديناميكية


const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', () => {
  import('./export-as-pdf.js')
    .then(module => {
      module.exportAsPdf()
    })
    .catch(err => {
      //      -  
    })
})

كما ترى ، يمكنك الآن تنظيم التحميل البطيء للوحدات عن طريق التحميل فقط عند الحاجة إلى الوحدة المناسبة. هذا يقلل من حمل النظام ويزيد من سرعة تحميل الصفحة.

بناء الوعد


إذا كنت بحاجة إلى القيام ببعض الإجراءات فقط إذا تم حل جميع الوعود بنجاح ، فيمكنك استخدام الطريقة Promise.all(). صحيح أن هذه الطريقة لها عيب واحد. ستقوم الطريقة بإلقاء خطأ إذا تم رفض وعد واحد على الأقل تم تمريره إليها. وهذا يعني أنه لن يتم تنفيذ الإجراء اللازم حتى يتم حل جميع الوعود بنجاح.

قد لا تحتاج هذا. ربما يناسبك السيناريو التالي: "النتيجة ليست مهمة بالنسبة لي. أحتاج إلى تنفيذ الكود بعد الانتهاء من جميع الوعود ". في هذه الحالة ، تكون الطريقة مفيدة لك Promise.allSettled(). يتم حل الوعد المقابل بنجاح فقط بعد الانتهاء من الوعود الأخرى. لا يهم إذا عملوا بنجاح أو دون جدوى.

▍ كود باستخدام بناء Promise.all


const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.all(PromiseArray)
  .then(data => console.log('all resolved! here are the resolve values:', data))
  .catch(err => console.log('got rejected! reason:', err))
//got rejected! reason: null

يبدو أنه Promise.allيعطي خطأ بعد رفض أحد الوعود المحولة إليه.

▍ كود يستخدم البناء Promise.allSettled


const PromiseArray = [
    Promise.resolve(100),
    Promise.reject(null),
    Promise.resolve("Data release"),
    Promise.reject(new Error('Something went wrong'))];
Promise.allSettled(PromiseArray).then(res =>{
console.log(res);
}).catch(err => console.log(err));
//[
//{status: "fulfilled", value: 100},
//{status: "rejected", reason: null},
//{status: "fulfilled", value: "Data release"},
//{status: "rejected", reason: Error: Something went wrong ...}
//]

وهنا على الرغم من رفض بعض الوعود ، إلا أنها Promise.allSettledتعيد النتائج التي أصدرتها جميع الوعود التي نقلت إليها.

ميزات بارزة أخرى


data نوع بيانات BigInt


BigIntيتيح لك نوع البيانات الجديد العمل مع الأرقام التي يتجاوز طولها طول الأرقام التي يمكنك العمل بها في JavaScript قبل ظهورها ( pow(2,53)-1). صحيح أن نوع البيانات هذا غير متوافق مع الإصدارات السابقة لما كان في اللغة من قبل. لا يدعم معيار IEEE 754 ، وهو الأساس للعمل مع الأرقام في JavaScript ، الأرقام التي يمكن العمل معهاBigInt

▍ طريقة String.prototype.matchAll


ترتبط الطريقة String.prototype.matchAll()بالتعبيرات العادية. تقوم بإرجاع مكرر ، مما يسمح لك بالعمل مع جميع التطابقات الموجودة في سلسلة باستخدام تعبير عادي ، بما في ذلك المجموعات .

property الملكية العالمية globalThis


تحتوي الخاصية العمومية globalThisعلى مرجع للكائن العمومي المقابل للبيئة التي يتم تنفيذ التعليمات البرمجية فيها. في المستعرض ، يتم تمثيل الكائن العام بالكائن window. في Node.js ، هذا كائن global. في عمال الويب ، هذا كائن self.

ما أكثر الابتكارات التي تحبها في ES2020؟


All Articles