Panduan JavaScript Bagian 9: Tinjauan Umum tentang Standar ES7, ES8, dan ES9

Hari ini, di bagian kesembilan dari terjemahan manual JavaScript, tinjauan umum akan dibuat dari fitur-fitur yang muncul dalam bahasa berkat standar ES7, ES8, dan ES9.

Bagian 1: program pertama, fitur bahasa, standar
Bagian 2: gaya kode dan struktur program
Bagian 3: variabel, tipe data, ekspresi, objek
Bagian 4: fungsi
Bagian 5: array dan loop
Bagian 6: pengecualian, titik koma, literal wildcard
Bagian 7: mode ketat, kata kunci ini, acara, modul, perhitungan matematis
Bagian 8: Gambaran Umum Fitur ES6
Bagian 9: Gambaran Umum Standar ES7, ES8, dan ES9



Standar ES7


Standar ES7, yang, sesuai dengan terminologi resmi, disebut ES2016, dirilis pada musim panas 2016. Dia, dibandingkan dengan ES6, dibawa ke bahasa tidak banyak yang baru. Secara khusus, kita berbicara tentang hal-hal berikut:

  • Array.prototype.includes() .
  • Operator eksponensial.

▍ Metode Array.prototype.includes ()


Metode Array.prototype.includes() dirancang untuk memeriksa keberadaan elemen dalam array. Menemukan yang diinginkan dalam array, mengembalikan true , bukan menemukan - false . Sebelum ES7, metode indexOf() digunakan untuk melakukan operasi yang sama, yang mengembalikan, jika elemen ditemukan, indeks pertama yang dapat ditemukan dalam array. Jika indexOf() tidak menemukan elemen, ia mengembalikan angka -1 .

Menurut aturan konversi tipe JavaScript, angka -1 dikonversi menjadi true . Sebagai hasilnya, untuk memeriksa hasil operasi indexOf() seseorang harus menggunakan konstruksi yang tidak nyaman dari bentuk berikut.

 if ([1,2].indexOf(3) === -1) { console.log('Not found') } 

Jika dalam situasi yang sama, dengan asumsi indexOf() , tanpa menemukan elemen, mengembalikan false , menggunakan sesuatu seperti yang ditunjukkan di bawah ini, kode tidak akan berfungsi dengan benar.

 if (![1,2].indexOf(3)) { // console.log('Not found') } 

Dalam kasus ini, ternyata konstruksi ![1,2].indexOf(3) false .

Menggunakan metode includes() , perbandingan seperti itu terlihat jauh lebih logis.

 if (![1,2].includes(3)) { console.log('Not found') } 

Dalam hal ini, konstruksi [1,2].includes(3) mengembalikan false , nilai ini adalah operator ! berubah menjadi true dan konsol menerima pesan yang menyatakan bahwa item dalam array tidak ditemukan.

▍ operator eksponensial


Operator eksponensial melakukan fungsi yang sama dengan metode Math.pow() , tetapi lebih nyaman untuk menggunakannya daripada fungsi perpustakaan, karena merupakan bagian dari bahasa.

 Math.pow(4, 2) == 4 ** 2 //true 

Operator ini dapat dianggap sebagai tambahan yang menyenangkan untuk JS, yang berguna dalam aplikasi yang melakukan perhitungan tertentu. Operator serupa ada dalam bahasa pemrograman lain.

Standar ES8


Standar ES8 (ES2017) dirilis pada tahun 2017. Dia, seperti ES7, tidak membawa banyak ke bahasa. Yaitu, kita berbicara tentang fitur-fitur berikut:

  • Menambahkan string ke panjang tertentu.
  • Metode Object.values() .
  • Metode Object.entries() .
  • Metode Object.getOwnPropertyDescriptors() .
  • Membuntuti koma dalam parameter fungsi.
  • Fungsi asinkron.
  • Bekerja dengan memori bersama dan operasi atom.

▍Menambahkan garis dengan panjang tertentu


ES8 memperkenalkan dua metode objek String baru - padStart() dan padEnd() .

Metode padStart() mengisi baris saat ini dengan baris lain sampai garis akhir mencapai panjang yang diinginkan. Pengisian terjadi di awal baris (kiri). Inilah cara menggunakan metode ini.

 str.padStart(targetLength [, padString]) 

Di sini str adalah garis saat ini, targetLength adalah panjang dari garis akhir (jika kurang dari panjang garis saat ini, garis ini akan dikembalikan tanpa perubahan), padString adalah parameter opsional - garis yang digunakan untuk mengisi garis saat ini. Jika padString tidak ditentukan, karakter spasi digunakan untuk padString garis saat ini dengan panjang yang ditentukan.

Metode padEnd() mirip dengan padStart() , tetapi baris diisi di sebelah kanan.

Pertimbangkan contoh penggunaan metode ini.

 const str = 'test'.padStart(10) const str1 = 'test'.padEnd(10,'*') console.log(`'${str}'`) //'      test' console.log(`'${str1}'`) //'test******' 

Di sini, ketika menggunakan padStart() dengan hanya panjang yang diinginkan dari string yang dihasilkan, spasi ditambahkan ke awal string asli. Saat menggunakan padEnd() dengan panjang baris terakhir dan baris untuk mengisinya, karakter * ditambahkan ke akhir baris asli.

▍ Metode Object.values ​​()


Metode ini mengembalikan array yang berisi nilai properti objek sendiri, yaitu properti yang berisi objek itu sendiri, dan bukan yang dapat diakses melalui rantai prototipe.

Inilah cara menggunakannya.

 const person = { name: 'Fred', age: 87 } const personValues = Object.values(person) console.log(personValues) // ['Fred', 87] 

Metode ini juga berlaku untuk array.

▍ Metode Object.entries ()


Metode ini mengembalikan array, masing-masing elemen yang juga merupakan array yang mengandung, dalam format [key, value] , kunci dan nilai properti objek sendiri.

 const person = { name: 'Fred', age: 87 } const personValues = Object.entries(person) console.log(personValues) // [['name', 'Fred'], ['age', 87]] 

Saat menerapkan metode ini ke array, indeks elemen ditampilkan sebagai kunci, dan apa yang disimpan dalam array di indeks terkait ditampilkan sebagai nilai.

▍ metode getOwnPropertyDescriptors ()


Metode ini mengembalikan informasi tentang semua properti objek itu sendiri. Set atribut (deskriptor) dikaitkan dengan properti objek. Secara khusus, kita berbicara tentang atribut-atribut berikut:

  • value - nilai properti dari objek.
  • writable - berisi true jika properti dapat diubah.
  • get - berisi fungsi getter yang terkait dengan properti, atau, jika tidak ada fungsi seperti itu, undefined .
  • set - berisi fungsi setter untuk properti atau undefined .
  • configurable - jika false - properti tidak dapat dihapus, atributnya tidak dapat diubah kecuali untuk nilainya.
  • enumerable - jika benar terkandung dalam properti ini - itu enumerable.

Inilah cara menggunakan metode ini.

 Object.getOwnPropertyDescriptors(obj) 

Dibutuhkan objek yang informasinya perlu Anda ketahui, dan mengembalikan objek yang berisi informasi ini.

 const person = { name: 'Fred', age: 87 } const propDescr = Object.getOwnPropertyDescriptors(person) console.log(propDescr) /* { name:  { value: 'Fred',    writable: true,    enumerable: true,    configurable: true }, age:  { value: 87,    writable: true,    enumerable: true,    configurable: true } } */ 

Mengapa metode ini dibutuhkan? Faktanya adalah memungkinkan Anda untuk membuat salinan kecil objek, menyalin, di samping properti lainnya, getter dan setter. Ini tidak dapat dilakukan dengan menggunakan metode Object.assign() , yang muncul dalam standar ES6, untuk menyalin objek.

Contoh berikut memiliki objek dengan setter yang menampilkan, menggunakan console.log() , apa yang mereka coba tulis ke properti terkait.

 const person1 = { set name(newName) {     console.log(newName) } } person1.name = 'x' // x 

Mari kita coba salin objek ini menggunakan metode assign() .

 const person2 = {} Object.assign(person2, person1) person2.name = 'x' //     ,    

Seperti yang Anda lihat, pendekatan ini tidak berhasil. Properti name , yang merupakan setter pada objek asli, sekarang direpresentasikan sebagai properti biasa.

Sekarang kita akan menyalin objek menggunakan metode Object.defineProperties() (muncul di ES5.1) dan Object.getOwnPropertyDescriptors() .

 const person3 = {} Object.defineProperties(person3, Object.getOwnPropertyDescriptors(person1)) person3.name = 'x' //x 

Di sini, penyetel tetap dalam salinan objek.

Perlu dicatat bahwa batasan khusus untuk Object.assign() juga merupakan karakteristik dari metode Object.create() ketika digunakan untuk mengkloning objek.

▍Completion koma pada parameter fungsi


Fitur ini memungkinkan Anda untuk meninggalkan koma di akhir daftar parameter atau argumen, masing-masing, ketika mendeklarasikan dan ketika memanggil fungsi.

 const doSomething = ( var1, var2, ) => { //... } doSomething( 'test1', 'test2', ) 

Ini meningkatkan kegunaan sistem kontrol versi. Yaitu, kita berbicara tentang fakta bahwa ketika menambahkan parameter baru ke suatu fungsi, Anda tidak perlu mengubah kode yang ada hanya untuk memasukkan koma.

▍Fungsi Asinkron


Konstruksi async/await wait telah muncul dalam standar ES2017, yang dapat dianggap sebagai inovasi terpenting dari versi bahasa ini.

Fungsi asinkron adalah kombinasi dari janji dan generator, mereka menyederhanakan konstruksi yang sebelumnya membutuhkan sejumlah besar kode templat dan rantai janji yang tidak nyaman untuk dijelaskan. Bahkan, kita berbicara tentang abstraksi tingkat tinggi atas janji.

Ketika janji muncul dalam standar ES2015, mereka dirancang untuk memecahkan masalah yang ada dengan kode asinkron, yang mereka lakukan. Tetapi selama dua tahun yang berbagi standar ES2015 dan ES2017, menjadi jelas bahwa janji tidak dapat dianggap sebagai solusi akhir untuk masalah ini.

Secara khusus, janji-janji itu ditujukan untuk memecahkan masalah "panggilan balik neraka", tetapi, setelah menyelesaikan masalah ini, mereka sendiri tidak menunjukkan sisi terbaiknya karena kompleksitas kode yang digunakan. Faktanya, konstruksi async/await menyelesaikan masalah janji dan meningkatkan kegunaan kode asinkron.

Pertimbangkan sebuah contoh.

 function doSomethingAsync() { return new Promise((resolve) => {     setTimeout(() => resolve('I did something'), 3000) }) } async function doSomething() { console.log(await doSomethingAsync()) } console.log('Before') doSomething() console.log('After') 

Kode ini akan menampilkan yang berikut ke konsol.

 Before After I did something 

Seperti yang Anda lihat, setelah memanggil doSomething() program terus berjalan, setelah Before , After ditampilkan di konsol, dan setelah tiga detik berlalu, I did something .

Panggilan fungsi asinkron serial


Jika perlu, fungsi asinkron dapat membentuk sesuatu seperti serangkaian panggilan. Desain seperti itu dibedakan oleh keterbacaan yang lebih baik daripada yang serupa, hanya berdasarkan janji. Ini bisa dilihat pada contoh berikut.

 function promiseToDoSomething() { return new Promise((resolve)=>{     setTimeout(() => resolve('I did something'), 10000) }) } async function watchOverSomeoneDoingSomething() { const something = await promiseToDoSomething() return something + ' and I watched' } async function watchOverSomeoneWatchingSomeoneDoingSomething() { const something = await watchOverSomeoneDoingSomething() return something + ' and I watched as well' } watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => { console.log(res) // I did something and I watched and I watched as well }) 

▍ Memori bersama dan operasi atom


Di sini kita berbicara tentang objek SharedArrayBuffer , yang memungkinkan kita untuk menggambarkan area memori bersama, dan objek Atomics , yang berisi serangkaian operasi atom dalam bentuk metode statis. Rincian tentang kemungkinan yang diberikan benda-benda ini kepada programmer dapat ditemukan di sini .

Standar ES9


ES9 (ES2018) adalah versi terbaru dari standar pada saat publikasi materi ini. Berikut adalah fitur utamanya:

  • Terapkan pernyataan spread dan rest ke objek.
  • Iterator Asinkron.
  • Metode Promise.prototype.finally() .
  • Peningkatan ekspresi reguler.

▍Aplikasi operator penyebaran dan istirahat ke objek


Kami telah berbicara tentang operator lain dan yang menyebar yang muncul di ES6 dan dapat digunakan untuk bekerja dengan array. Keduanya terlihat seperti tiga titik. Operator sisanya, dalam contoh berikut ini merusak array, memungkinkan Anda untuk menempatkan elemen pertama dan kedua dalam konstanta first dan second , dan semua sisanya di konstanta yang others .

 const numbers = [1, 2, 3, 4, 5] const [first, second, ...others] = numbers console.log(first) //1 console.log(second) //2 console.log(others) //[ 3, 4, 5 ] 

Operator spread memungkinkan Anda meneruskan array ke fungsi yang mengharapkan daftar parameter reguler.

 const numbers = [1, 2, 3, 4, 5] const sum = (a, b, c, d, e) => a + b + c + d + e const res = sum(...numbers) console.log(res) //15 

Sekarang, menggunakan pendekatan yang sama, Anda bisa bekerja dengan objek. Berikut adalah contoh penggunaan pernyataan lainnya dalam operasi penugasan yang merusak.

 const { first, second, ...others } = { first: 1, second: 2, third: 3, fourth: 4, fifth: 5 } console.log(first) //1 console.log(second) //2 console.log(others) //{ third: 3, fourth: 4, fifth: 5 } 

Berikut adalah pernyataan spread yang digunakan saat membuat objek baru berdasarkan yang sudah ada. Contoh ini melanjutkan yang sebelumnya.

 const items = { first, second, ...others } console.log(items) //{ first: 1, second: 2, third: 3, fourth: 4, fifth: 5 } 

ItAkron sinkron


Konstruksi for-await-of memungkinkan Anda untuk memanggil fungsi asinkron yang mengembalikan janji dalam loop. Loop semacam itu menunggu resolusi janji sebelum melanjutkan ke langkah berikutnya. Ini tampilannya.

 for await (const line of readLines(filePath)) { console.log(line) } 

Pada saat yang sama, perlu dicatat bahwa loop tersebut harus digunakan dalam fungsi asinkron - cara yang sama seperti ketika bekerja dengan async/await konstruksi.

▍ Metode Promise.prototype.finally ()


Jika janji berhasil diselesaikan, metode selanjutnya then() dipanggil. Jika terjadi kesalahan, metode catch() dipanggil. Metode finally() memungkinkan Anda untuk mengeksekusi beberapa kode terlepas dari apa yang terjadi sebelumnya.

 fetch('file.json') .then(data => data.json()) .catch(error => console.error(error)) .finally(() => console.log('finished')) 

▍ Peningkatan Ekspresi Reguler


Ekspresi reguler memiliki kemampuan untuk memeriksa string secara retrospektif ( ?<= ). Ini memungkinkan Anda untuk mencari konstruksi tertentu di baris sebelum yang ada beberapa konstruksi lainnya.

Kemampuan untuk mendahului pemeriksaan menggunakan ?= Konstruksikan hadir dalam ekspresi reguler yang diterapkan dalam JavaScript sebelum standar ES2018. Cek tersebut memberi tahu Anda apakah fragmen lain mengikuti fragmen tertentu dari suatu garis.

 const r = /Roger(?= Waters)/ const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //false console.log(res2) //true 

Konstruksi ?! melakukan operasi yang berlawanan - kecocokan hanya akan ditemukan jika garis lain tidak mengikuti garis yang diberikan.

 const r = /Roger(?! Waters)/g const res1 = r.test('Roger is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //true console.log(res2) //false 

Dalam verifikasi retrospektif, sebagaimana telah disebutkan, konstruksinya ?<= digunakan.

 const r = /(?<=Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //false console.log(res2) //true 

Operasi yang berlawanan dengan yang dijelaskan dapat dilakukan menggunakan konstruksi ?<! .

 const r = /(?<!Roger) Waters/ const res1 = r.test('Pink Waters is my dog') const res2 = r.test('Roger is my dog and Roger Waters is a famous musician') console.log(res1) //true console.log(res2) //false 

Unicode regex escape sequence


Dalam ekspresi reguler, Anda bisa menggunakan kelas \d yang cocok dengan digit apa pun, kelas \s yang cocok dengan karakter spasi apa pun, kelas \w yang cocok dengan karakter alfanumerik apa pun, dan sebagainya. Fitur yang dipermasalahkan memperluas serangkaian kelas yang dapat digunakan dalam ekspresi reguler, memungkinkan Anda untuk bekerja dengan urutan Unicode. Kita berbicara tentang kelas \p{} dan kebalikan dari kelas \P{} .

Dalam Unicode, setiap karakter memiliki seperangkat properti. Properti ini ditunjukkan dalam kurung grup \p{} . Jadi, misalnya, properti Script menentukan keluarga bahasa yang dimiliki karakter, properti ASCII , logis, true untuk karakter ASCII, dan sebagainya. Misalnya, kami akan mencari tahu apakah beberapa baris hanya berisi karakter ASCII.

 console.log(r.test('abc')) //true console.log(r.test('ABC@')) //true console.log(r.test('ABC')) //false 

Properti ASCII_Hex_Digit true hanya untuk karakter yang dapat digunakan untuk menulis angka heksadesimal.

 const r = /^\p{ASCII_Hex_Digit}+$/u console.log(r.test('0123456789ABCDEF')) //true console.log(r.test('H')) //false 

Ada banyak properti serupa lainnya yang digunakan dengan cara yang sama seperti yang dijelaskan di atas. Diantaranya adalah Uppercase , Lowercase , White_Space , Alphabetic , Emoji .

Misalnya, inilah cara menggunakan properti Script untuk menentukan alfabet mana yang digunakan dalam sebuah string. Di sini kita memeriksa string untuk penggunaan alfabet Yunani.

 const r = /^\p{Script=Greek}+$/u console.log(r.test('ελληνικά')) //true console.log(r.test('hey')) //false 

Detail tentang properti ini dapat ditemukan di sini .

Grup Bernama


Grup karakter yang diambil di ES2018 dapat diberi nama. Ini tampilannya.

 const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ const result = re.exec('2015-01-02') console.log(result) /* [ '2015-01-02', '2015', '01', '02', index: 0, input: '2015-01-02', groups: { year: '2015', month: '01', day: '02' } ] */ 

Tanpa menggunakan grup bernama, data yang sama hanya akan tersedia sebagai elemen array.

 const re = /(\d{4})-(\d{2})-(\d{2})/ const result = re.exec('2015-01-02') console.log(result) /* [ '2015-01-02', '2015', '01', '02', index: 0, input: '2015-01-02', groups: undefined ] */ 

Bendera regex s


Menggunakan flag s menghasilkan karakter . (titik) akan, antara lain, cocok dengan karakter baris baru. Tanpa tanda ini, suatu periode cocok dengan karakter apa pun kecuali untuk baris baru.

 console.log(/hi.welcome/.test('hi\nwelcome')) // false console.log(/hi.welcome/s.test('hi\nwelcome')) // true 

Ringkasan


Dengan materi ini, kami menyelesaikan publikasi terjemahan manual JavaScript ini . Kami berharap publikasi ini membantu mereka yang belum pernah menggunakan JavaScript sebelumnya untuk mengambil langkah pertama dalam pemrograman dalam bahasa ini.

Pembaca yang budiman! Jika Anda belum pernah menulis JS sebelumnya dan menguasai bahasa ini dalam panduan ini, silakan bagikan tayangan Anda.

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


All Articles