EcmaScript 10 - JavaScript لهذا العام (ES2019)

تحول توحيد JS إلى دورة تحديث مدتها عام واحد ، وبداية العام هي وقت رائع للتعرف على ما ينتظرنا في الذكرى السنوية - الإصدار العاشر من EcmaScript!


ES 9 هو الإصدار الحالي من المواصفات .


ES 10 لا تزال مسودة .


حتى الآن ، تتضمن المرحلة 4 # بعض الاقتراحات.


وفي المرحلة 3 # - عشرات كاملة!


من هذه ، في رأيي ، الأكثر إثارة للاهتمام هي الحقول الخاصة للفئات # ، قواعد اللغة shebang للنصوص # ، أرقام الدقة التعسفية # ، الوصول إلى السياق العام # والواردات الديناميكية # .



KDPV: مغناطيس أصفر مع نقش "JS ES10" على شاشة الشاشة - من kasper.green و elfafeya.art
صورة بواسطة: kasper.green؛ المغناطيس الأصفر: elfafeya.art & kasper.green


المحتويات


خمس مراحل #


المرحلة 4 - النهائي


catch - أصبحت الوسيطة اختيارية # ؛


Symbol().description - Symbol().description - موصل لوصف الرمز # ؛


' EcmaScript' - تحسين التوافق مع تنسيق JSON # ؛


.toString() - طريقة تحديث النموذج الأولي # .


Object.fromEntries() - إنشاء كائن من مجموعة من الأزواج - مفتاح \ value # ؛


•. .flat() و .flatMap() هما .flatMap() للصفيف .




المرحلة 3 - مرحلة ما قبل الإصدار #


# - كل شيء خاص في الفصول الدراسية ، من خلال octotorp # ؛


#!/usr/bin/env node - قواعد اللغة shebang للنصوص # ؛


BigInt() - بدائية جديدة ، لأرقام الدقة التعسفية # ؛


globalThis - طريقة جديدة للوصول إلى السياق العام # ؛


import(dynamic) - استيراد ديناميكي .


import.meta - معلومات التعريف حول الوحدة النمطية المحملة # ؛


JSON.stringify() - إصلاح الأسلوب # ؛


RegExp - الميزات المهملة # ؛


.trimStart() و .trimEnd() - أساليب سلسلة النموذج الأولي # ؛


.matchAll() - .match() مع العلامة العالمية # ؛


النتائج #




خمس مراحل


المرحلة 0Strawman Basting فكرة يمكن تنفيذها من خلال البرنامج المساعد Babel .


المرحلة 1 Pro اقتراح الاقتراح التحقق من صلاحية الفكرة.


المرحلة 2مسودة مشروع بدء تطوير المواصفات ؛


المرحلة 3 ، مرشح المرشح معاينة المواصفات.


المرحلة 4 ֍ تم الانتهاء من الانتهاء من الإصدار النهائي للمواصفات لهذا العام.




سننظر فقط في المرحلة 4 - المعيار الفعلي.


والمرحلة 3 - التي على وشك أن تصبح جزءًا منها.





֍ المرحلة 4


هذه التغييرات هي بالفعل القياسية.


حجة اختياري catch


https://github.com/tc39/proposal-optional-catch-binding


قبل ES 10 ، كانت catch تتطلب وسيطة مطلوبة لجمع معلومات الخطأ ، حتى لو لم يتم استخدامها:


 function isValidJSON(text) { try { JSON.parse(text); return true; } catch(unusedVariable) { //    return false; } } 


لم تتم ترقية Edge بعد إلى ES 10 ، ومن المتوقع أن تتعطل مع وجود خطأ.


بدءًا من الإصدار ES 10 ، يمكن حذف الأقواس وسيصبح catch مثل قطرتين من الماء مثل try .



تم تحديث My Chrome بالفعل إلى ES 10 ، وفي بعض الأماكن إلى المرحلة 3 . المزيد من لقطات الشاشة ستكون من Chrome


شفرة المصدر
 function isValidJSON(text) { try { JSON.parse(text); return true; } catch { //   return false; } } 



الوصول إلى أوصاف الرابط الرمزي


https://tc39.imtqy.com/proposal-Symbol-description/


يمكن الحصول على وصف ارتباط رمزي بشكل غير مباشر باستخدام طريقة toString ():


 const symbol_link = Symbol("Symbol description") String(symbol_link) // "Symbol(Symbol description)" 

بدءًا من ES 10 ، تحتوي الأحرف على خاصية وصف للقراءة فقط. يسمح لك بالحصول على وصف للرمز دون أي رقص مع الدف:


 symbol_link.description // "Symbol description" 

إذا لم يتم تحديد الوصف ، فسوف يعود - undefined :


 const without_description_symbol_link = Symbol() without_description_symbol_link.description // undefined const empty_description_symbol_link = Symbol('') empty_description_symbol_link.description // "" 



سلاسل EcmaScript متوافقة مع JSON


https://github.com/tc39/proposal-json-superset


تزعم EcmaScript ، قبل إصدارها العاشر ، أن JSON هي مجموعة فرعية من JSON.parse ، لكن هذا ليس صحيحًا.


يمكن أن تحتوي خطوط JSON على فواصل أسطر غير محمية U+2028 LINE SEPARATOR والفقرات U+2029 PARAGRAPH SEPARATOR .


خطوط ECMAScript تصل إلى الإصدار العاشر - لا.


إذا قمت بالاتصال eval() في Edge مع السلسلة "\u2029" ،
يتصرف كما لو فعلنا فاصل أسطر - في منتصف الكود:




مع خطوط ES 10 - كل شيء على ما يرام:





.toString() طريقة النموذج الأولي. .toString()


http://tc39.imtqy.com/Function-prototype-toString-revision/


تغيير الأهداف
  • إزالة متطلبات غير متوافقة للخلف:

إذا تعذر على التطبيق إنشاء سلسلة تعليمات برمجية مصدر تلبي هذه المعايير ، فيجب أن تُرجع السلسلة التي سيقوم eval بإلقاء استثناء فيها بسبب خطأ في بناء الجملة.

  • توضيح شرط "المكافئ وظيفيًا" ؛


  • توحيد تمثيل السلسلة للوظائف المدمجة والكائنات المضيفة ؛


  • توضيح متطلبات العرض التقديمي على أساس "الخصائص الفعلية" للكائن ؛


  • تأكد من أن تحليل السلسلة يحتوي على نفس دالة الوظيفة وقائمة المعلمات مثل الأصل ؛


  • بالنسبة للوظائف المعرفة باستخدام كود ECMAScript ، يجب على toString إرجاع جزء من النص المصدر من بداية الرمز المميز الأول إلى نهاية الرمز المميز المقابل للبناء النحوي المقابل ؛


  • بالنسبة للكائنات الوظيفية المضمّنة ، يجب ألا يُرجع toString أي شيء سوى NativeFunction ؛


  • بالنسبة للكائنات التي لم يتم تعريفها باستخدام كود ECMAScript ، يجب أن تقوم toString بارجاع دالة NativeFunction ؛


  • بالنسبة للوظائف التي تم إنشاؤها ديناميكيًا (منشئي الوظيفة أو المولد) ، يجب على toString توليف النص المصدر ؛


  • بالنسبة لجميع الكائنات الأخرى ، يجب أن يرسل toString استثناء TypeError.



 //   function () { console.log('My Function!'); }.toString(); // function () { console.log('My Function!'); } //     Number.parseInt.toString(); // function parseInt() { [native code] } //     function () { }.bind(0).toString(); // function () { [native code] } //     Symbol.toString(); // function Symbol() { [native code] } //     Function().toString(); // function anonymous() {} //    - function* () { }.toString(); // function* () { } // .call   ,   ,  Function.prototype.toString.call({}); // Function.prototype.toString requires that 'this' be a Function" 



إنشاء كائن باستخدام الأسلوب Object.fromEntries()


https://github.com/tc39/proposal-object-from-entries


يعمل في الكروم


التناظرية من _.fromPairs من lodash :


 Object.fromEntries([['key_1', 1], ['key_2', 2]]) // {key_1: 1; key_2: 2} 



صفائف أحادية البعد مع. .flat() و. .flatMap()


https://github.com/tc39/proposal-flatMap


يعمل في الكروم


حصل الصفيف على نماذج أولية. .flat() و. .flatMap() ، والتي تشبه بشكل عام تطبيقات lodash ، ولكن لا تزال لديها بعض الاختلافات. وسيطة اختيارية - لتعيين أقصى عمق اجتياز شجرة:


 const deep_deep_array = [ '≥0 —  ', [ '≥1 —  ', [ '≥2 —  ', [ '≥3 —  ', [ '≥4 —  ' ] ] ] ] ] // 0 —     deep_deep_array.flat(0) //  ["≥0 —  ", Array(2)] // 1 —    deep_deep_array.flat() //  [" ", " ", Array(2)] deep_deep_array.flat(2) //  [" ", " ", " ", Array(2)] deep_deep_array.flat(100500) // [" ", " ", " ", " ", " "] 

.flatMap() يكافئ الاتصال بالتتابع .map().flat() . يجب أن تقوم دالة رد الاتصال التي تم تمريرها إلى الطريقة بإرجاع صفيف سيصبح جزءًا من صفيف مسطح مشترك:


 ['Hello', 'World'].flatMap(word => [...word]) // ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"] 

باستخدام .flat() و .map() ، يمكن إعادة كتابة المثال مثل هذا:


  ['Hello', 'World'].map(word => [...word]).flat() // ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"] 

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







3 المرحلة 3


الاقتراحات التي ظهرت من حالة المسودة ، لكنها لم تدخل بعد الصيغة النهائية للمعيار.


خاص \ ثابت \ الأساليب العامة \ خصائص \ سمات الطبقات


https://github.com/tc39/proposal-class-fields
https://github.com/tc39/proposal-private-methods
https://github.com/tc39/proposal-static-class-features


في بعض اللغات ، يوجد اتفاق على استدعاء أساليب خاصة بمساحة مرئية (" _ " - مثل هذه القطعة ، قد تعرف هذه العلامة باسم خاطئ - أسفل السطر) .


على سبيل المثال ، مثل هذا:


 <?php class AdultContent { private $_age = 0; private $_content = '…is dummy example content (•)(•) —3 (.)(.) only for adults…'; function __construct($age) { $this->_age = $age; } function __get($name) { if($name === 'content') { return " (age: ".$this->_age.") → ".$this->_getContent()."\r\n"; } else { return 'without info'; } } private function _getContent() { if($this->_contentIsAllowed()) { return $this->_content; } return 'Sorry. Content not for you.'; } private function _contentIsAllowed() { return $this->_age >= 18; } function __toString() { return $this->content; } } echo "<pre>"; echo strval(new AdultContent(10)); // (age: 10) → Sorry. Content not for you echo strval(new AdultContent(25)); // (age: 25) → …is dummy example content (•)(•) —3 only for adults… $ObjectAdultContent = new AdultContent(32); echo $ObjectAdultContent->content; // (age: 32) → …is dummy example content (•)(•) —3 only for adults… ?> 

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


أنا شخصياً أعجبت بفكرة استخدام مساحة مرئية كبادئة للوظائف التي ترجع this . بحيث يمكن دمجها في سلسلة من المكالمات.


ذهب مطورو مواصفات EcmaScript إلى أبعد من ذلك وجعلوا البادئة octotorp (" # " - شعرية ، هاش) جزءًا من بناء الجملة.


يمكن إعادة كتابة المثال السابق على ES 10 على النحو التالي:


 export default class AdultContent { //    #age = 0 #adult_content = '…is dummy example content (•)(•) —3 (.)(.) only for adults…' constructor(age) { this.#setAge(age) } //    static #userIsAdult(age) { return age > 18 } //   get content () { return `(age: ${this.#age}) → ` + this.#allowed_content } //   get #allowed_content() { if(AdultContent.userIsAdult(this.age)){ return this.#adult_content } else { return 'Sorry. Content not for you.' } } //   #setAge(age) { this.#age = age } toString () { return this.#content } } const AdultContentForKid = new AdultContent(10) console.log(String(AdultContentForKid)) // (age: 10) → Sorry. Content not for you. console.log(AdultContentForKid.content) // (age: 10) → Sorry. Content not for you. const AdultContentForAdult = new AdultContent(25) console.log(String(AdultContentForAdult)) // (age: 25) → …is dummy example content (•)(•) —3 (.)(.) only for adults… console.log(AdultContentForAdult.content) // (age: 25) → …is dummy example content (•)(•) —3 (.)(.) only for adults… 

المثال معقد بشكل غير ضروري لإظهار الخصائص والأساليب والسمات الخاصة دفعة واحدة. ولكن بشكل عام ، JS - يرضي العين بإيجازها مقارنة بإصدار PHP. لا توجد وظيفة خاصة بالنسبة لك ، ولا توجد فواصل منقوطة في نهاية السطر ، ونقطة بدلاً من "->" للتعمق في الكائن.


games اسمه. للأسماء الديناميكية ، كائنات الوكيل.


يبدو أن تفاهات ، ولكن بعد التبديل إلى JS ، هناك رغبة أقل وأقل للعودة إلى PHP.


بالمناسبة ، لا تتوفر برامج الوصول الخاصة إلا مع بابل 7.3.0 والإصدارات الأحدث.


في وقت كتابة هذا التقرير ، كان أحدث إصدار من npmjs.com هو 7.2.2


نتطلع إلى المرحلة 4!




قواعد شيبانج


https://github.com/tc39/proposal-hashbang


Hashbang هي وسيلة مألوفة لدى Unix لتحديد مترجم لملف قابل للتنفيذ:


 #!/usr/bin/env node //   'use strict'; console.log(1); 

 #!/usr/bin/env node //   export {}; console.log(1); 

يقوم Chrome SyntaxError: Invalid or&nbsp;unexpected token بإلقاء SyntaxError: Invalid or&nbsp;unexpected token على نسخة SyntaxError: Invalid or&nbsp;unexpected token مماثلة


أعداد كبيرة مع BigInt


https://github.com/tc39/proposal-bigint


دعم المتصفح

دعم المتصفح ل BigInt () البدائية


العدد الصحيح الأقصى الذي يمكن استخدامه بأمان في JavaScript (2⁵³ - 1):


 console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991 

BigInt مطلوب لاستخدام أرقام الدقة التعسفي.


يتم الإعلان عن هذا النوع بعدة طرق:


 //  'n'       910000000000000100500n // 910000000000000100500n //      BigInt()   BigInt( 910000000000000200500 ) // 910000000000000200500n //     -  BigInt( "910000000000000300500" ) // 910000000000000300500n //      1642  BigInt( "" ) \\ 

هذا نوع بدائي جديد:


 typeof 123; // → 'number' typeof 123n; // → 'bigint' 

يمكن مقارنتها بالأرقام العادية:


 42n === BigInt(42); // → true 42n == 42; // → true 

ولكن يجب إجراء العمليات الرياضية ضمن نوع واحد:


 20000000000000n/20n // 1000000000000n 20000000000000n/20 // Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions 

يتم دعم ناقص Unary ، بينما يعيد unary plus خطأ:


  -2n // -2n +2n // Uncaught TypeError: Cannot convert a BigInt value to a number 


globalThis - طريقة جديدة للوصول إلى السياق العالمي


https://github.com/tc39/proposal-global


يعمل في الكروم


نظرًا لأن تطبيقات النطاق العالمي تعتمد على محرك معين ، فعليك فعل شيء مثل هذا من قبل:


 var getGlobal = function () { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('unable to locate global object'); }; 

وحتى هذا الخيار لم يضمن أن كل شيء سوف يعمل بشكل مؤكد.


globalThis طريقة شائعة لجميع المنصات للوصول إلى النطاق العالمي:


 //      globalThis.Array(1,2,3) // [1, 2, 3] //        globalThis.myGLobalSettings = { it_is_cool: true } //        globalThis.myGLobalSettings // {it_is_cool: true} 



import(dynamic)


https://github.com/tc39/proposal-dynamic-import


دعم المتصفح

دعم المتصفح للواردات الحيوية


أردت متغيرات في خطوط الاستيراد مع عمليات الاستيراد الديناميكية ، أصبح هذا ممكنًا:


 import(`./language-packs/${navigator.language}.js`) 

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


لذلك ، يمكنك تحميل الوحدات - المؤجلة عند الضرورة:


 element.addEventListener('click', async () => { //   await    const module = await import(`./events_scripts/supperButtonClickEvent.js`) module.clickEvent() }) 

بناءً على ذلك ، يبدو هذا بمثابة استدعاء للدالة import() ، لكنه لا يرث من Function.prototype ، مما يعني أنها لن تنجح في الاتصال من خلال call أو apply :


 import.call("example this", "argument") // Uncaught SyntaxError: Unexpected identifier 



import.meta - معلومات التعريف حول الوحدة النمطية المحملة.


https://github.com/tc39/proposal-import-meta


يعمل في الكروم


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


 console.log(import.meta); // { url: "file:///home/user/my-module.js" } 



JSON.stringify() طريقة JSON.stringify()


https://github.com/tc39/proposal-well-formed-stringify


يتطلب القسم 8.1 من RFC 8259 أن يتم ترميز نص JSON الذي تم تبادله خارج نظام بيئي مغلق باستخدام UTF-8 ، ولكن يمكن لـ JSON.stringify إرجاع السلاسل التي تحتوي على نقاط كود غير ممثلة في UTF-8 (على وجه الخصوص ، نقاط رمز بديلة من U + D800 إلى U + DFFF)


وبالتالي فإن السطر \uDF06\uD834 بعد معالجة JSON.stringify () يتحول إلى \\udf06\\ud834 :


 /*         */ JSON.stringify('\uDF06\uD834') '"\\udf06\\ud834"' JSON.stringify('\uDEAD') '"\\udead"' 

هذا لا ينبغي أن يكون ، والمواصفات الجديدة بإصلاح هذا. تم تحديث Edge و Chrome بالفعل.




إهمال ميزات RegExp


https://github.com/tc39/proposal-regexp-legacy-features


مواصفات وظائف RegExp القديمة ، مثل RegExp.$1 ، و RegExp.prototype.compile() الأسلوب.




أساليب سلسلة النموذج الأولي .trimStart() و .trimEnd()


https://github.com/tc39/proposal-string-left-right-trim


يعمل في الكروم


عن طريق القياس مع الأساليب .padStart() و .padEnd() ، قم بقطع مسافة بيضاء في بداية ونهاية السطر ، على التوالي:


 const one = " hello and let "; const two = "us begin. "; console.log( one.trimStart() + two.trimEnd() ) // "hello and let us begin." 



.matchAll () هو أسلوب سلسلة نموذج جديد.


https://github.com/tc39/proposal-string-matchall


يعمل في الكروم


يعمل مثل طريقة .match() مع العلم g التشغيل ، لكنه يعرض مكرر:


 const string_for_searh = 'olololo' //         string_for_searh.match(/o/) // ["o", index: 0, input: "olololo", groups: undefined] //       string_for_searh.match(/o/g) // ["o", "o", "o", "o"] //   string_for_searh.matchAll(/o/) // {_r: /o/g, _s: "olololo"} //        , //      .match    for(const item of string_for_searh.matchAll(/o/)) { console.log(item) } // ["o", index: 0, input: "olololo", groups: undefined] // ["o", index: 2, input: "olololo", groups: undefined] // ["o", index: 4, input: "olololo", groups: undefined] // ["o", index: 6, input: "olololo", groups: undefined] 

يجب أن تكون الوسيطة تعبيرًا عاديًا ، وإلا سيتم طرح استثناء:


 'olololo'.matchAll('o') // Uncaught TypeError: o is not a regexp! 







ملخص


جلبت المرحلة 4 المزيد من التغييرات التجميلية. الفائدة هي المرحلة 3 . تم بالفعل تنفيذ معظم الاقتراحات في Chrome ، وتتطلع خصائص الكائنات بالفعل إلى الأمام.






تصويبات في المقال



إذا لاحظت عدم دقة في المقالة أو خطأ أو هناك شيء تكملة له ، فيمكنك كتابة رسالة شخصية لي ، لكن من الأفضل استخدام مستودع المقالات https://github.com/KasperGreen/es10 بنفسك. للمساهمة الفعالة ، سأمنح ميدالية مغناطيسية صفراء مع KDPV.


المواد ذات الصلة


المواد باللغة الإنجليزية الإصدار الحالي من معيار Ecma-262


المواد باللغة الإنجليزية مسودة الإصدار التالي من معيار Ecma-262


ECMAScript


حقول فئة خاصة جديدة # في JavaScript


مقال عن حبري نظرة عامة على معايير ES7 و ES8 و ES9


شيبانج


مقال عن حبري BigInt - الحساب الطويل في JavaScript


مقال عن حبري مسار وحدة جافا سكريبت


المواد باللغة الإنجليزية لماذا لا الخاص س


مقال عن حبري اقتراح ECMAScript: Array.prototype. {Flat، flatMap}


مجالات الصف العام والخاص


جافا سكريبت: الكبير كله حسنا لماذا




محدث (مارس):


تم تغيير الحالة إلى المرحلة - 4 :


.trimStart() و .trimEnd() - أساليب سلسلة النموذج الأولي # ؛


.matchAll() - .match() مع العلامة العالمية # ؛


KDPV بديل مع مغناطيس أصفر من elfafeya.art
صورة بواسطة: kasper.green؛ المغناطيس الأصفر: elfafeya.art & kasper.green

Source: https://habr.com/ru/post/ar437806/


All Articles