EcmaScript 10 - JavaScript Tahun Ini (ES2019)

Standardisasi JS telah beralih ke siklus pembaruan satu tahun, dan awal tahun adalah waktu yang tepat untuk mencari tahu apa yang menanti kita di hari peringatan - edisi kesepuluh EcmaScript!


ES 9 adalah versi spesifikasi saat ini .


ES 10 masih konsep .


Hanya ada beberapa penawaran di Tahap 4 # hari ini.


Dan di Tahap 3 # - selusin!


Dari semua ini, menurut saya, yang paling menarik adalah bidang privat kelas # , tata bahasa shebang untuk skrip # , jumlah presisi # yang sewenang-wenang , akses ke konteks global # dan impor dinamis # .



KDPV: Magnet kuning dengan tulisan "JS ES10" di layar monitor - dari kasper.green & elfafeya.art
Foto oleh: kasper.green; Magnet kuning: elfafeya.art & kasper.green


Isi


Lima tahap #


Tahap 4 - Final #


catch - argumen telah menjadi opsional # ;


Symbol().description - aksesor ke deskripsi simbol # ;


' EcmaScript' - peningkatan kompatibilitas dengan format JSON # ;


.toString() - metode prototipe diperbarui # .


Object.fromEntries() - membuat objek dari array berpasangan - key \ value # ;


.flat() dan .flatMap() adalah metode array # prototipe .




Tahap 3 - Pra-rilis #


# - semuanya pribadi di kelas, melalui octotorp # ;


#!/usr/bin/env node - tata bahasa shebang untuk skrip # ;


BigInt() - primitif baru, untuk nomor presisi sembarang # ;


globalThis - cara baru untuk mengakses konteks global # ;


import(dynamic) - impor dinamis # ;


import.meta - informasi meta tentang modul # yang dimuat ;


JSON.stringify() - memperbaiki metode # ;


RegExp - fitur usang # ;


.trimStart() dan .trimEnd() - metode string prototipe # ;


.matchAll() - .match() dengan flag global # ;


Hasil #




Lima tahap


Tahap 0Basting Strawman Sebuah ide yang dapat diimplementasikan melalui plugin Babel- ;


Tahap 1Proposal Proposal Verifikasi kelayakan gagasan.;


Tahap 2Draft Draft Mulai pengembangan spesifikasi.;


Tahap 3 ↓ Spesifikasi Kandidat Pratinjau Kandidat ;;


Tahap 4 ֍ Selesai Versi terakhir dari spesifikasi untuk tahun ini selesai.




Kami hanya akan mempertimbangkan Tahap 4 - standar de facto.


Dan Tahap 3 - yang akan menjadi bagian darinya.





֍ Tahap 4


Perubahan ini sudah standar.


Argumen opsional untuk catch


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


Sebelum ES 10, catch membutuhkan argumen yang diperlukan untuk mengumpulkan informasi kesalahan, bahkan jika itu tidak digunakan:


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


Edge belum ditingkatkan ke ES 10, dan diperkirakan rusak karena kesalahan.


Dimulai dengan edisi ES 10, tanda kurung dapat dihilangkan dan catch akan menjadi seperti dua tetes air seperti try .



Chrome saya telah diperbarui ke ES 10, dan di beberapa tempat ke Tahap 3 . Tangkapan layar lebih lanjut akan dari Chrome


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



Akses deskripsi tautan simbolik


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


Deskripsi tautan simbolis dapat diperoleh secara tidak langsung menggunakan metode toString ():


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

Dimulai dengan ES 10, karakter memiliki properti deskripsi yang hanya baca. Ini memungkinkan Anda untuk mendapatkan deskripsi simbol tanpa tarian dengan rebana:


 symbol_link.description // "Symbol description" 

Jika deskripsi tidak ditentukan, itu akan kembali - 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 Strings Kompatibel dengan JSON


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


EcmaScript, sebelum edisi kesepuluhnya, mengklaim bahwa JSON adalah bagian dari JSON.parse , tetapi ini tidak benar.


Garis JSON dapat berisi pemisah garis unshielded U+2028 LINE SEPARATOR dan paragraf U+2029 PARAGRAPH SEPARATOR .


ECMAScript berbaris hingga versi kesepuluh - no.


Jika Anda memanggil eval() di Edge dengan string "\u2029" ,
berperilaku seolah-olah kita melakukan break baris - tepat di tengah-tengah kode:




Dengan ES 10 baris - semuanya baik-baik saja:





Penyempurnaan metode prototipe .toString()


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


Ubah Tujuan
  • hapus persyaratan yang tidak kompatibel mundur:

Jika implementasi tidak dapat membuat string kode sumber yang memenuhi kriteria ini, itu harus mengembalikan string yang eval akan melemparkan pengecualian dengan kesalahan sintaksis.

  • mengklarifikasi persyaratan "setara secara fungsional";


  • membakukan representasi string dari fungsi bawaan dan objek host;


  • memperjelas persyaratan presentasi berdasarkan “karakteristik aktual” suatu objek;


  • pastikan bahwa penguraian string berisi isi fungsi yang sama dan daftar parameter seperti aslinya;


  • untuk fungsi yang didefinisikan menggunakan kode skrip ECMAS, toString harus mengembalikan sebuah fragmen teks sumber dari awal token pertama hingga akhir token terakhir yang sesuai dengan konstruksi tata bahasa yang sesuai;


  • untuk objek fungsional bawaan, toString tidak boleh mengembalikan apa pun kecuali fungsi Native;


  • untuk objek yang dipanggil yang tidak didefinisikan menggunakan kode ECMAScript, toString harus mengembalikan NativeFunction;


  • untuk fungsi yang dibuat secara dinamis (fungsi atau generator konstruktor) toString harus mensintesis teks sumber;


  • untuk semua objek lain, toString harus membuang pengecualian 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" 



Membuat objek menggunakan metode Object.fromEntries()


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


bekerja di chrome


Analog dari _.fromPairs dari lodash :


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



Array satu dimensi dengan .flat() dan .flatMap()


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


bekerja di chrome


Array memperoleh prototipe .flat() dan .flatMap() , yang umumnya mirip dengan implementasi lodash , tetapi masih memiliki beberapa perbedaan. Argumen opsional - menetapkan kedalaman traversal pohon maksimum:


 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() sama dengan memanggil berurutan .map().flat() . Fungsi callback yang diteruskan ke metode harus mengembalikan array yang akan menjadi bagian dari array flat umum:


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

Hanya menggunakan .flat() dan .map() , contohnya dapat ditulis ulang seperti ini:


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

Perhatikan juga bahwa .flatMap() , tidak seperti .flat() tidak memiliki pengaturan kedalaman perayapan. Jadi hanya level pertama yang akan dilem.







֍ Tahap 3


Proposal yang telah muncul dari status draf, tetapi belum memasuki versi final standar.


Private \ static \ public methods \ properties \ atribut kelas


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


Dalam beberapa bahasa ada perjanjian untuk memanggil metode pribadi dengan ruang yang terlihat (" _ " - bagian seperti itu, Anda mungkin tahu tanda ini dengan nama yang salah - garis bawah) .


Misalnya, seperti ini:


 <?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… ?> 

Biarkan saya mengingatkan Anda - ini hanya kesepakatan. Tidak ada yang mencegah menggunakan awalan untuk tujuan lain, menggunakan awalan yang berbeda, atau tidak menggunakannya sama sekali.


Secara pribadi, saya terkesan dengan gagasan untuk menggunakan ruang yang terlihat sebagai awalan untuk fungsi yang mengembalikan this . Jadi mereka dapat digabungkan menjadi rantai panggilan.


Pengembang spesifikasi EcmaScript melangkah lebih jauh dan membuat bagian awalan- octotorp (" # " -lattice, hash) dari sintaks.


Contoh sebelumnya pada ES 10 dapat ditulis ulang sebagai berikut:


 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… 

Contohnya tidak perlu rumit untuk menunjukkan properti, metode, dan atribut pribadi sekaligus. Tetapi secara umum, JS - menyenangkan mata dengan keringkasannya dibandingkan dengan versi PHP. Tidak ada fungsi pribadi _... bagi Anda, tidak ada titik koma di akhir baris, dan sebuah titik alih-alih “->” untuk masuk lebih dalam ke objek.


Getter yang diberi nama. Untuk nama dinamis, objek proxy.


Tampaknya menjadi hal sepele, tetapi setelah beralih ke JS, semakin sedikit keinginan untuk kembali ke PHP.


Omong-omong, aksesor pribadi hanya tersedia dengan Babel 7.3.0 dan yang lebih baru.


Pada saat penulisan, versi npmjs.com terbaru adalah 7.2.2


Menantikan Tahap 4!




Tata Bahasa Shebang


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


Hashbang adalah cara yang Unix kenal dengan menentukan penerjemah untuk file yang dapat dieksekusi:


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

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

Chrome SyntaxError: Invalid or&nbsp;unexpected token melempar SyntaxError: Invalid or&nbsp;unexpected token pada SyntaxError: Invalid or&nbsp;unexpected token serupa


Angka besar dengan BigInt


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


dukungan browser

Dukungan browser untuk BigInt () primitif


Bilangan bulat maksimum yang dapat digunakan dengan aman dalam JavaScript (2⁵³ - 1):


 console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991 

BigInt diperlukan untuk menggunakan angka presisi acak.


Jenis ini dideklarasikan dengan beberapa cara:


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

Ini adalah tipe primitif baru:


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

Ini dapat dibandingkan dengan angka biasa:


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

Tetapi operasi matematika harus dilakukan dalam satu jenis:


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

Unary minus didukung, unary plus mengembalikan kesalahan:


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


globalThis - cara baru untuk mengakses konteks global


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


bekerja di chrome


Karena implementasi lingkup global bergantung pada mesin tertentu, Anda harus melakukan sesuatu seperti ini sebelumnya:


 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'); }; 

Dan bahkan opsi ini tidak menjamin bahwa semuanya akan bekerja dengan pasti.


globalThis adalah cara umum bagi semua platform untuk mengakses ruang lingkup global:


 //      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


dukungan browser

Dukungan browser untuk impor dinamis


Saya ingin variabel di jalur impor Dengan impor dinamis, ini menjadi mungkin:


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

Impor dinamis adalah operasi asinkron. Mengembalikan janji bahwa, setelah memuat modul, mengembalikannya ke fungsi panggilan balik.


Oleh karena itu, Anda dapat memuat modul - ditangguhkan saat diperlukan:


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

Secara sintaksis, ini terlihat seperti panggilan ke fungsi import() , tetapi tidak mewarisi dari Function.prototype , yang artinya tidak akan berhasil menelepon melalui call atau apply :


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



import.meta - informasi meta tentang modul yang dimuat.


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


bekerja di chrome


Dalam kode modul yang dimuat, menjadi mungkin untuk memperoleh informasi tentangnya. Sekarang ini hanya alamat tempat modul dimuat:


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



JSON.stringify() metode JSON.stringify()


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


Bagian 8.1 dari RFC 8259 mensyaratkan bahwa teks JSON yang dipertukarkan di luar ekosistem tertutup dikodekan menggunakan UTF-8, tetapi JSON.stringify dapat mengembalikan string yang berisi titik kode yang tidak terwakili dalam UTF-8 (khususnya, titik kode pengganti) dari U + D800 ke U + DFFF)


Jadi baris \uDF06\uD834 setelah pemrosesan JSON.stringify () berubah menjadi \\udf06\\ud834 :


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

Seharusnya tidak demikian, dan spesifikasi baru memperbaikinya. Edge dan Chrome telah diperbarui.




Fitur RegExp yang sudah tidak digunakan lagi


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


Spesifikasi untuk fungsi RegExp lawas, seperti RegExp.$1 , dan metode RegExp.prototype.compile() .




Metode String Prototipe .trimStart() dan .trimEnd()


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


bekerja di chrome


Dengan analogi dengan metode .padStart() dan .padEnd() , potong spasi putih di awal dan akhir baris, masing-masing:


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



.matchAll () adalah metode string prototipe baru.


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


bekerja di chrome


Bekerja seperti metode .match() dengan flag g dihidupkan, tetapi mengembalikan iterator:


 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] 

Argumen harus berupa ekspresi reguler, jika tidak maka pengecualian akan dilemparkan:


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







Ringkasan


Tahap 4 membawa lebih banyak perubahan kosmetik. Bunga adalah Tahap 3 . Sebagian besar saran di Chrome sudah diterapkan, dan properti objek benar-benar menantikan.






Koreksi dalam artikel



Jika Anda melihat ada ketidakakuratan dalam artikel, kesalahan, atau ada sesuatu yang harus ditambahkan, Anda dapat menulis pesan pribadi kepada saya , tetapi lebih baik menggunakan repositori artikel https://github.com/KasperGreen/es10 sendiri. Untuk kontribusi aktif, saya akan memberikan medali magnet kuning dengan KDPV.


Materi Terkait


Materi dalam bahasa ingggris Versi terkini dari standar Ecma-262


Materi dalam bahasa ingggris Draf versi standar Ecma-262 berikutnya


Naskah ECMAS


Bidang # private class baru di JavaScript


Artikel tentang Habré Tinjauan Standar ES7, ES8, dan ES9


Shebang


Artikel tentang Habré BigInt - aritmatika panjang dalam JavaScript


Artikel tentang Habré Jalur modul JavaScript


Materi dalam bahasa ingggris Kenapa tidak pribadi x


Artikel tentang Habré Proposal ECMAScript: Array.prototype. {Flat, flatMap}


Bidang kelas publik dan swasta


JavaScript: The Big Whole Well Why




UPD (Maret):


Mengubah status ke Tahap - 4 :


.trimStart() dan .trimEnd() - metode string prototipe # ;


.matchAll() - .match() dengan flag global # ;


Alternatif KDPV dengan magnet kuning dari elfafeya.art
Foto oleh: kasper.green; Magnet kuning: elfafeya.art & kasper.green

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


All Articles