4 ميزات ثورية لـ JavaScript من المستقبل

تطورت JavaScript سريعًا وديناميكيًا منذ إصدار معيار ECMAScript 6 (ES6). بفضل حقيقة أنه يتم الآن إصدار إصدارات جديدة من معيار ECMA-262 سنويًا ، وبفضل العمل العملاق لجميع الشركات المصنعة للمتصفحات ، أصبحت JS واحدة من أكثر لغات البرمجة شيوعًا في العالم.



لقد كتبت مؤخرًا عن الميزات الجديدة التي تم تقديمها في ES2020... في حين أن بعض هذه الاحتمالات مثيرة للاهتمام ، فلا يوجد ما يستحق أن يُطلق عليه "الثوري". هذا أمر مفهوم نظرًا لحقيقة أن مواصفات JS يتم تحديثها كثيرًا هذه الأيام. اتضح أن أولئك الذين يعملون على المعيار لديهم ببساطة فرص أقل لتقديم شيء خاص باستمرار في اللغة ، مثل وحدات ES6 أو وظائف الأسهم. لكن هذا لا يعني أن شيئًا جديدًا حصريًا لن يظهر في النهاية في اللغة. في واقع الأمر ، هذا ما أريد أن أتحدث عنه اليوم. أود أن أتحدث عن 4 احتمالات يمكن أن يطلق عليها على المدى الطويل ثورية. هم الآن في مراحل مختلفة من العملية.







تنسيق المقترحات. هذا ، من ناحية ، يعني أننا قد لا نراهم في JavaScript أبدًا ولا نراهم ، ومن ناحية أخرى ، فإن وجود مثل هذه الجمل يمنحنا الأمل في أننا سنلتقي بها يومًا ما في اللغة.



مصممون



سنبدأ بالميزة التي ربما تكون الأكثر طلبًا لتضمينها في اللغة ، والتي يُثار الكثير من الجلبة حولها. قبل عامين ، كتبوا عنها حرفيًا في كل مكان. إنه عن الديكور .



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



ألق نظرة على المثال التالي:



function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}


هنا قررت المضي قدمًا بحذر وقدمت مثالًا على استخدام أدوات تزيين TypeScript . فعلت هذا بشكل أساسي لإظهار الفكرة العامة. في مقتطف الشفرة أعلاه ، أنشأنا مصممًا وقمنا sealedبتطبيقه على الفصل Greeter. كما ترى ، فإن مصمم الديكور هو ببساطة وظيفة لها حق الوصول إلى مُنشئ الفئة التي يتم تطبيقها عليها (هذا هو الهدف). نستخدم إشارة إلى المُنشئ ، وكذلك طريقة Object.seal()لجعل الفئة غير قابلة للتوسعة.



من أجل تطبيق المصمم على فصل دراسي ، نكتب اسم المصمم بأيقونة @قبل إعلان الفصل مباشرة. نتيجة لذلك ، اتضح أنه قبل ظهور الإعلان الطبقي ، هناك بناء للشكل @[name]، والذي يبدو في حالتنا @sealed.



يمكنك التحقق من وظائف المصمم عن طريق تجميع رمز TS هذا مع تمكين الخيار experimentalDecoratorsومحاولة تغيير النموذج الأولي للفئة:



Greeter.prototype.test = "test"; // ERROR


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



قررت استخدام TypeScript لإظهار المصممين لسبب وجيه. النقطة المهمة هي أن اقتراح تضمين أدوات الزينة في JavaScript كان موجودًا منذ بضع سنوات. وهي الآن "فقط" في المرحلة الثانية من الاتفاق من أصل 4. كل من بناء الجملة وقدرات المصممين من هذا الاقتراح تتغير باستمرار. لكن هذا لا يمنع مجتمع JS من استخدام هذا المفهوم. لكي تكون مقتنعًا بهذا ، يكفي إلقاء نظرة على مشاريع ضخمة مفتوحة المصدر مثل TypeScript أو Angular v2 +.



صحيح أن كل هذا ، بمرور الوقت ، ومع تطور الاقتراح ، يؤدي إلى مشكلة تتعلق بعدم توافق المواصفات. وبالتحديد ، تطورت مواصفات مصمم الديكور كثيرًا منذ تقديم الاقتراح ، لكن العديد من المشاريع لم يتم تنفيذها بعد. مثال TypeScript الموضح أعلاه هو عرض توضيحي لتنفيذ إصدار أقدم من الاقتراح. يمكن قول الشيء نفسه عن Angular ، وحتى Babel (على الرغم من أنه في حالة Babel ، يمكننا القول أن العمل جار الآن لتطبيق إصدار أحدث من هذه المواصفات). بشكل عام ، الإصدار الأحدث من الاقتراح ، الذي يستخدم كلمة رئيسية وصيغة decoratorمناسبة للربط ، لم يجد بعد أي استخدام ملحوظ.



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



العوالم



الآن دعنا نبطئ قليلاً ونتحدث عن ميزة واحدة ليست معقدة مثل الديكور. نحن نتحدث عن المجالات .



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



حل المتصفح الحالي لهذه المشكلة هو استخدام العناصر<iframe>، وفي بعض الحالات الخاصة - في استخدام العاملين على الويب. في بيئة Node.js ، يتم حل نفس المشكلة باستخدام وحدة نمطية vmأو باستخدام عمليات فرعية . تم تصميم Realms API لحل مثل هذه المشاكل.



تهدف واجهة برمجة التطبيقات هذه إلى السماح للمطورين بإنشاء بيئات عالمية منفصلة تسمى النطاقات. كل منطقة من هذا القبيل لها كيانات عالمية خاصة بها. ألق نظرة على المثال التالي:



var x = 39;
const realm = new Realm();

realm.globalThis.x; // undefined
realm.globalThis.x = 42; // 42
realm.globalThis.x; // 42

x; // 39


هنا نقوم بإنشاء كائن جديد Realmباستخدام المُنشئ المناسب. من الآن فصاعدًا ، لدينا وصول كامل إلى النطاق الجديد وكائناته العالمية من خلال خاصية globalThis(مقدمة في ES2020). هنا يمكنك أن ترى أن متغيرات "الحاضنة" الرئيسية منفصلة عن المتغيرات في النطاق الذي أنشأناه.



بشكل عام ، تم التخطيط لـ Realms API كآلية بسيطة للغاية ، لكنها آلية مفيدة. تحتوي واجهة برمجة التطبيقات هذه على مجموعة محددة جدًا من حالات الاستخدام. لا يمنحنا مستوى أعلى من الأمان ، أو القدرة على رمز متعدد مؤشرات الترابط. لكنها تتواءم بشكل مثالي ، دون خلق عبء غير ضروري على النظام ، مع مهمتها الرئيسية ، مع توفير القدرات الأساسية لإنشاء بيئات معزولة.



اقتراح Realms API هو حاليًا في المرحلة الثانية من التفاوض. عندما يصل في النهاية إلى المعيار ، يتوقع المرء أن يتم استخدامه في المكتبات "الثقيلة" التي تعتمد على النطاق العالمي ، في برامج تحرير الأكواد ذات وضع الحماية عبر الإنترنت ، في تطبيقات مختلفة تستهدف اختبارات.



افعل التعبيرات



يتضمن بناء جملة JavaScript ، مثل بناء جملة معظم لغات البرمجة ، العبارات والتعبيرات. يتمثل الاختلاف الأكثر وضوحًا بين هذه التركيبات في أنه يمكن استخدام التعبيرات كقيم (أي ، يمكن تخصيصها للمتغيرات ، وتمريرها إلى الوظائف ، وما إلى ذلك) ، بينما لا يمكن استخدام العبارات على هذا النحو.



بسبب هذا الاختلاف ، تعد التعبيرات هي الخيار الأكثر تفضيلاً للحصول على كود أكثر وضوحًا وإحكامًا. في JavaScript ، يمكنك رؤية ذلك من خلال النظر في شعبية تعبيرات الوظائف ، والتي تتضمن وظائف السهم ، مقابل إعلانات الوظائف ، وبيانات الوظيفة. ونرى نفس الموقف إذا قارنا طرق التكرار على المصفوفات (مثلforEach()) بالدورات. وينطبق الشيء نفسه على المبرمجين الأكثر تقدمًا عند مقارنة عامل ثلاثي وبيان if.



يهدف اقتراح do-expression ، الذي يخضع حاليًا لمرحلة التفاوض 1 ، إلى زيادة تعزيز قدرات تعبيرات JS. وبالمناسبة ، لا تخلط بين مفهوم "افعل التعبير" والحلقات do…while، لأنهما أشياء مختلفة تمامًا.



هذا مثال:



let x = do {
  if (foo()) {
    f();
  } else if (bar()) {
    g();
  } else {
    h();
  }
};


هذا هو بناء الجملة من عبارة do-expression. بشكل عام ، لدينا قطعة من كود JS ملفوفة في بناء do {}. يتم "إرجاع" آخر تعبير في هذا البناء كقيمة نهائية لتعبير do بالكامل.



يمكن تحقيق تأثير مشابه (ولكن ليس متطابقًا) باستخدام IIFE (التعبير عن الوظيفة الذي تم استدعاؤه فورًا). ولكن في حالة تعبيرات do ، فإن تركيبها المضغوط يبدو جذابًا للغاية. هنا ، مع وظائف مماثلة ، لا تحتاج إلى أي منهما return، أو أي هياكل مساعدة قبيحة مثل(() => {})()... لهذا السبب أعتقد أنه بمجرد دخول التعبيرات إلى المعيار ، فإن تأثيرها على JavaScript سيكون مشابهًا لتأثير وظائف الأسهم. ملاءمة التعبيرات والنحو الودّي ، إذا جاز التعبير ، في حزمة واحدة ، تبدو مغرية للغاية.



نمط مطابقة



هذه الفرصة هي الأخيرة في هذه المادة ، لكنها ليست الأخيرة من حيث الأهمية. يهدف هذا الاقتراح إلى إدخال آلية مطابقة الأنماط في اللغة .



قد تكون على دراية بتعليمات JS switch. إنه مشابه if-else، لكن خياراته محدودة أكثر قليلاً ، وهو بالتأكيد مناسب بشكل أفضل لتنظيم اختيار أحد البدائل العديدة. هكذا تبدو:



switch (value) {
  case 1:
    // ...
    break;
  case 2:
    // ...
    break;
  case 3:
    // ...
    break;
  default:
    // ...
    break;
}


أنا شخصياً أعتقد أن التعليمات switchأضعف من التعليمات if، حيث switchيمكنها مقارنة ما يتم تمريره إليها فقط بقيم محددة. يمكن التحايل على هذا القيد ، لكن لا يمكنني التفكير في السبب. بالإضافة إلى ذلك ، فإن التعليمات switchمحملة بشكل زائد بالعناصر المساعدة. على وجه الخصوص ، نحن نتحدث عن التعليمات break.



يمكن اعتبار آلية مطابقة النمط كإصدار أكثر فاعلية ، وقائم على التعبير ، وربما أكثر تنوعًا من البيان switch. بدلاً من مجرد مقارنة القيم ، تسمح آلية مطابقة النمط للمطور بمقارنة القيم مع الأنماط المخصصة (القوالب) القابلة للتخصيص بدرجة كبيرة. فيما يلي مقتطف رمز يوضح مثالاً لواجهة برمجة التطبيقات المقترحة:



const getLength = vector => case (vector) {
  when { x, y, z } -> Math.hypot(x, y, z)
  when { x, y } -> Math.hypot(x, y)
  when [...etc] -> vector.length
}
getLength({x: 1, y: 2, z: 3})


يستخدم صيغة غير معتادة تمامًا لجافا سكريبت (على الرغم من أنه يعتمد على بناء الجملة الموجود في لغات مثل Rust أو Scala ) ، والذي يحتوي على بعض أوجه التشابه مع التعليمات المعروفة لدينا بالفعل switch. هنا ، بدلاً من الكلمة الأساسية ، switchيتم استخدام كلمة caseتشير إلى بداية الكتلة التي يتم فيها التحقق من القيمة. ثم ، داخل الكتلة ، باستخدام الكلمة الأساسيةwhen، نصف القوالب التي نريد التحقق من صحة القيم بها. بناء جملة القوالب يشبه بناء جملة آلية تدمير الكائن المتوفرة بالفعل في اللغة. يمكنك مقارنة القيم بالكائنات التي تحتوي على خصائص محددة ، ويمكنك مقارنتها بقيم الخصائص على الكائنات ، وبكيانات أخرى كثيرة. لمعرفة المزيد حول هذه الآلية - ألق نظرة على هذا المستند.



بعد وصف القالب ، يوجد سهم ("سهم مسطح" ->) يشير إلى التعبير (في المنظور - حتى إلى قيمة مختلفة) ، والذي يجب تقييمه عند البحث عن تطابق مع النمط.



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



النتيجة



بهذا أختتم قصتي حول الميزات الثورية لجافا سكريبت ، والتي قد نراها في اللغة في المستقبل. هناك احتمالات أخرى مماثلة، مثل مقترحات ل مكتبة القياسية الخارجية و مشغل عبر خط انابيب . لكنني اخترت لهذه المادة فقط ما بدا لي الأكثر إثارة للاهتمام. ضع في اعتبارك أن هذه الفرص لا تزال في مرحلة الاقتراح. يمكن أن تتغير بمرور الوقت. أو قد يحدث أنهم لم يدخلوا المعيار أبدًا. لكن إذا كنت تريد على أي حال أن تكون من بين أولئك الذين يستغلون مثل هذه الفرص قبل الآخرين ، أنصحك بإلقاء نظرة فاحصة على مشاريع مثل Babel... تولد هذه المشاريع الكثير من جمل JS (خاصة تلك المتعلقة ببناء الجملة). يسمح هذا لأي شخص بتجربة أحدث الميزات قبل فترة طويلة من ظهورها في تطبيقات اللغة.



ما هي أكثر الميزات التي تفتقدها في JavaScript؟






All Articles