Materi, bagian pertama dari terjemahan yang kami terbitkan hari ini, dikhususkan untuk fitur JavaScript standar baru yang dibahas pada konferensi
Google I / O 2019 . Secara khusus, di sini kita akan berbicara tentang ekspresi reguler, tentang bidang kelas, tentang bekerja dengan string.

Pemeriksaan Ekspresi Reguler
Ekspresi reguler (Ekspresi Reguler, singkatnya - RegEx atau RegExp) adalah teknologi pemrosesan string yang kuat yang diimplementasikan dalam banyak bahasa pemrograman. Ekspresi reguler sangat berguna dalam kasus-kasus di mana Anda perlu, misalnya, untuk mencari fragmen string dengan pola yang kompleks. Sampai saat ini, implementasi JavaScript dari ekspresi reguler memiliki segalanya kecuali melihat ke belakang.
Untuk memahami apa itu pemeriksaan retrospektif, mari kita bicara tentang lookaheads yang sudah didukung dalam JavaScript.
β
Bagian keduaβ Cek muka
Sintaks pemeriksaan terdepan dalam ekspresi reguler memungkinkan Anda untuk mencari fragmen string ketika diketahui bahwa fragmen lain berada di sebelah kanannya. Misalnya, saat bekerja dengan string
MangoJuice, VanillaShake, GrapeJuice
Anda dapat menggunakan sintaks dari pemeriksaan awal positif untuk menemukan kata yang segera diikuti oleh kata
Juice
. Dalam kasus kami, ini adalah kata
Mango
dan
Grape
.
Ada dua jenis cek terkemuka. Ini adalah lookaheads positif dan lookaheads negatif.
Pemeriksaan timah positif
Pemeriksaan awal positif digunakan untuk mencari garis di sebelah kanan yang merupakan garis lain yang sebelumnya diketahui. Berikut ini sintaks ekspresi reguler yang digunakan untuk pemeriksaan ini:
/[a-zA-Z]+(?=Juice)/
Template ini memungkinkan Anda untuk memilih kata-kata yang terdiri dari huruf kecil atau huruf besar, diikuti oleh kata
Juice
. Jangan bingung antara struktur yang menggambarkan pemeriksaan terkemuka dan retrospektif dengan kelompok tangkap. Meskipun kondisi pemeriksaan ini ditulis dalam tanda kurung, sistem tidak menangkapnya. Mari kita lihat contoh pemeriksaan timah positif.
const testString = "MangoJuice, VanillaShake, GrapeJuice"; const testRegExp = /[a-zA-Z]+(?=Juice)/g; const matches = testString.match( testRegExp ); console.log( matches );
Pemeriksaan Timbal Negatif
Jika kami mempertimbangkan, menggunakan baris di atas, mekanisme aksi pemeriksaan negatif, ternyata mereka memungkinkan Anda menemukan kata di sebelah kanan yang tidak ada kata
Juice
. Sintaks pemeriksaan awal negatif mirip dengan sintaks pemeriksaan positif. Namun, ada satu fitur di dalamnya, yaitu simbol
=
(sama) berubah menjadi simbol
!
(tanda seru). Begini tampilannya:
/[a-zA-Z]+(?!Juice)/
Ekspresi reguler ini memungkinkan Anda memilih semua kata di sebelah kanan yang tidak ada kata
Juice
. Tetapi ketika menerapkan template seperti itu, semua kata dalam baris akan dipilih (
MangoJuice, VanillaShake, GrapeJuice
). Faktanya adalah bahwa, menurut sistem, tidak ada satu kata pun di sini yang berakhir dengan
Juice
. Akibatnya, untuk mencapai hasil yang diinginkan, Anda perlu memperjelas ekspresi reguler dan menulis ulang seperti ini:
/(Mango|Vanilla|Grape)(?!Juice)/
Dengan menggunakan templat ini, Anda dapat memilih kata
Mango
, atau
Vanilla
, atau
Grape
, setelah itu tidak ada kata
Juice
. Berikut ini sebuah contoh:
const testString = "MangoJuice, VanillaShake, GrapeJuice"; const testRegExp = /(Mango|Vanilla|Grape)(?!Juice)/g; const matches = testString.match( testRegExp ); console.log( matches );
β Pemeriksaan Retrospektif
Dengan analogi dengan sintaks pemeriksaan terkemuka, sintaks pemeriksaan retrospektif memungkinkan Anda untuk memilih urutan karakter hanya jika di sebelah kiri urutan ini adalah pola yang diberikan. Misalnya, saat memproses string
FrozenBananas, DriedApples, FrozenFish
kita dapat menggunakan pemeriksaan retrospektif positif untuk menemukan kata di sebelah kiri yang terdapat kata
Frozen
. Dalam kasus kami, kata
Bananas
dan
Fish
sesuai dengan kondisi ini.
Ada, seperti halnya dengan pemeriksaan terkemuka, pemeriksaan retrospektif positif (terlihat positif di belakang) dan pemeriksaan retrospektif negatif (terlihat negatif atau negatif).
Ulasan retrospektif positif
Pemeriksaan retrospektif positif digunakan untuk mencari pola di sebelah kiri yang merupakan pola lainnya. Berikut adalah contoh sintaks yang digunakan untuk menggambarkan pemeriksaan tersebut:
/(?<=Frozen)[a-zA-Z]+/
Simbol
<
digunakan di sini, yang tidak dalam deskripsi pemeriksaan awal. Selain itu, kondisi dalam ekspresi reguler terletak tidak di sebelah kanan templat yang menarik bagi kami, tetapi di sebelah kiri. Menggunakan templat di atas, Anda dapat memilih semua kata yang dimulai dengan
Frozen
. Pertimbangkan sebuah contoh:
const testString = "FrozenBananas, DriedApples, FrozenFish"; const testRegExp = /(?<=Frozen)[a-zA-Z]+/g; const matches = testString.match( testRegExp ); console.log( matches );
Pemeriksaan Retrospektif Negatif
Mekanisme pemeriksaan retrospektif negatif memungkinkan Anda mencari pola pada garis di sebelah kiri yang tidak ada pola tertentu. Misalnya, jika Anda perlu memilih kata-kata yang tidak dimulai dengan
Frozen
di
FrozenBananas, DriedApples, FrozenFish
line, Anda dapat mencoba menggunakan ekspresi reguler ini:
/(?<!Frozen)[a-zA-Z]+/
Tapi, karena menggunakan konstruksi ini akan mengarah pada pemilihan semua kata dari string, karena tidak ada yang dimulai dengan
Frozen
, ekspresi reguler perlu diklarifikasi:
/(?<!Frozen)(Bananas|Apples|Fish)/
Berikut ini sebuah contoh:
const testString = "FrozenBananas, DriedApples, FrozenFish"; const testRegExp = /(?<!Frozen)(Bananas|Apples|Fish)/g; const matches = testString.match( testRegExp ); console.log( matches );
β Dukungan
Bagian ini dan bagian serupa lainnya akan memberikan informasi tentang tahap harmonisasi fitur yang dijelaskan JS dalam Komite Teknis 39 (Komite Teknis 39, TC39), yang bertanggung jawab dalam ECMA Internasional untuk mendukung spesifikasi ECMAScript. Bagian tersebut juga akan memberikan data tentang versi Chrome dan Node.js (dan terkadang pada versi Firefox), dimulai dengan mana Anda dapat menggunakan fitur yang sesuai.
Bidang kelas
Bidang kelas adalah konstruk sintaksis baru yang digunakan untuk mendefinisikan properti instance kelas (objek) di luar konstruktor kelas. Ada dua jenis bidang kelas: bidang kelas publik dan bidang kelas pribadi.
Fields Bidang kelas publik
Sampai saat ini, sifat-sifat objek harus didefinisikan di dalam konstruktor kelas. Properti ini bersifat publik (publik). Ini berarti bahwa mereka dapat diakses dengan bekerja dengan instance kelas (objek). Berikut adalah contoh menyatakan properti publik:
class Dog { constructor() { this.name = 'Tommy'; } }
Ketika itu perlu untuk membuat kelas yang akan memperpanjang kelas induk tertentu, perlu untuk memanggil
super()
di konstruktor kelas anak. Ini harus dilakukan sebelum propertinya dapat ditambahkan ke kelas anak. Begini tampilannya:
class Animal {} class Dog extends Animal { constructor() { super();
Berkat kemunculan sintaks bidang publik suatu kelas, dimungkinkan untuk menggambarkan bidang kelas di luar konstruktor. Sistem akan membuat panggilan implisit ke
super()
.
class Animal {} class Dog extends Animal { sound = 'Woof! Woof!';
Ketika secara implisit memanggil
super()
, semua argumen yang disediakan oleh pengguna saat membuat instance kelas diteruskan ke dalamnya (ini adalah perilaku standar JavaScript, tidak ada yang istimewa tentang bidang kelas privat). Jika konstruktor dari kelas induk membutuhkan argumen yang disiapkan dengan cara khusus, Anda perlu memanggil
super()
sendiri. Lihatlah hasil panggilan konstruktor implisit dari kelas induk saat membuat turunan dari kelas anak.
class Animal { constructor( ...args ) { console.log( 'Animal args:', args ); } } class Dog extends Animal { sound = 'Woof! Woof!';
β Bidang kelas pribadi
Seperti yang Anda ketahui, dalam JavaScript tidak ada pengubah akses ke bidang kelas seperti
public
,
private
, atau
protected
. Semua properti objek bersifat publik secara default. Ini berarti bahwa akses ke mereka tidak terbatas. Hal terdekat untuk membuat properti dari objek yang mirip dengan properti pribadi adalah dengan menggunakan tipe data
Symbol
. Ini memungkinkan Anda untuk menyembunyikan properti objek dari dunia luar. Anda mungkin menggunakan nama properti yang diawali dengan
_
(garis bawah) untuk menunjukkan bahwa properti yang sesuai harus dianggap dimaksudkan hanya untuk digunakan dalam objek. Namun, ini hanya semacam pemberitahuan bagi mereka yang akan menggunakan fasilitas ini. Ini tidak memecahkan masalah pembatasan nyata akses ke properti.
Berkat mekanisme bidang privat kelas, dimungkinkan untuk membuat properti kelas hanya dapat diakses di dalam kelas ini. Ini mengarah pada fakta bahwa mereka tidak dapat diakses dari luar dan bekerja dengan instance kelas (objek). Ambil contoh sebelumnya dan coba akses properti kelas dari luar, ketika awalan
_
digunakan.
class Dog { _sound = 'Woof! Woof!';
Seperti yang Anda lihat, menggunakan
_
awalan tidak menyelesaikan masalah kami. Bidang pribadi kelas dapat dideklarasikan dengan cara yang sama dengan bidang publik, tetapi alih-alih awalan dalam bentuk garis bawah, Anda harus menambahkan awalan dalam bentuk tanda pound (
#
) ke nama mereka. Upaya akses tidak sah ke properti pribadi objek yang dinyatakan dengan cara ini akan menghasilkan kesalahan berikut:
SyntaxError: Undefined private field
Berikut ini sebuah contoh:
class Dog { #sound = 'Woof! Woof!';
Perhatikan bahwa properti pribadi hanya dapat diakses dari kelas di mana mereka dinyatakan. Akibatnya, kelas turunan tidak dapat langsung menggunakan properti serupa dari kelas induk.
Bidang pribadi (dan publik) dapat dideklarasikan tanpa menuliskan nilai tertentu ke dalamnya:
class Dog { #name; constructor( name ) { this.#name = name; } showName() { console.log( this.#name ); } }
β Dukungan
Metode String .matchAll ()
Prototipe tipe data
String
memiliki metode
.match()
yang mengembalikan array fragmen string yang cocok dengan kondisi yang ditentukan oleh ekspresi reguler. Berikut ini contoh menggunakan metode ini:
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /([A-Z0-9]+)/g; console.log( colors.match( matchColorRegExp ) );
Ketika menggunakan metode ini, bagaimanapun, tidak ada informasi tambahan yang diberikan (seperti indeks) tentang fragmen string yang ditemukan. Jika Anda menghapus flag
g
dari ekspresi reguler yang dilewatkan ke metode
.match()
, itu akan mengembalikan array yang akan berisi informasi tambahan tentang hasil pencarian. Namun, dengan pendekatan ini, hanya fragmen pertama dari string yang cocok dengan ekspresi reguler yang akan ditemukan.
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /#([A-Z0-9]+)/; console.log( colors.match( matchColorRegExp ) );
Untuk mendapatkan sesuatu yang serupa, tetapi untuk beberapa bagian string, Anda harus menggunakan metode ekspresi reguler
.exec()
. Konstruksi yang diperlukan untuk ini lebih rumit daripada yang di mana metode string tunggal akan digunakan untuk mendapatkan hasil yang serupa. Secara khusus, di sini kita memerlukan
while
yang akan mengeksekusi sampai
.exec()
mengembalikan
null
. Menggunakan pendekatan ini, perlu diingat bahwa
.exec()
tidak mengembalikan iterator.
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /#([A-Z0-9]+)/g;
Untuk mengatasi masalah tersebut, kita sekarang dapat menggunakan metode string
.matchAll()
, yang mengembalikan iterator. Setiap panggilan ke metode
.next()
dari iterator ini
.next()
elemen berikutnya dari hasil pencarian. Hasilnya, contoh di atas dapat ditulis ulang sebagai berikut:
const colors = "#EEE, #CCC, #FAFAFA, #F00, #000"; const matchColorRegExp = /#([A-Z0-9]+)/g; console.log( ...colors.matchAll( matchColorRegExp ) );
β Dukungan
Grup Bernama dalam Ekspresi Reguler
Konsep grup dalam implementasi JavaScript dari mekanisme ekspresi reguler sedikit berbeda dari implementasi konsep serupa dalam bahasa lain. Yaitu, ketika menggunakan JavaScript, template RegEx ditempatkan dalam tanda kurung (kecuali ketika tanda kurung digunakan untuk pemeriksaan retrospektif atau lanjutan), templat menjadi grup.
Fragmen string yang ditangkap oleh grup akan tercermin dalam hasil penerapan ekspresi reguler.
Pada contoh sebelumnya, Anda bisa melihat bahwa elemen pertama array dengan hasil pencarian adalah elemen yang cocok dengan seluruh ekspresi reguler, dan yang kedua adalah elemen yang sesuai dengan grup. Berikut ini elemen array ini:
["#EEE", "EEE", index: 0, input: "<colors>"]
Jika ada beberapa grup dalam ekspresi reguler, maka mereka akan masuk ke hasil pemrosesan string dalam urutan deskripsi mereka dalam ekspresi reguler. Pertimbangkan sebuah contoh:
const str = "My name is John Doe."; const matchRegExp = /My name is ([az]+) ([az]+)/i; const result = str.match( matchRegExp );console.log( result );
Di sini Anda dapat melihat bahwa baris pertama dari output adalah seluruh baris yang sesuai dengan ekspresi reguler. Elemen kedua dan ketiga mewakili apa yang ditangkap oleh kelompok.
Menggunakan grup yang diberi nama memungkinkan Anda untuk menyimpan apa yang ditangkap
groups
objek
groups
, yang nama propertinya bersesuaian dengan nama yang ditetapkan untuk grup.
const str = "My name is John Doe."; const matchRegExp = /My name is (?<firstName>[az]+) (?<lastName>[az]+)/i; const result = str.match( matchRegExp ); console.log( result ); console.log( result.groups );
Perlu dicatat bahwa grup yang diberi nama berfungsi dengan baik bersama dengan metode
.matchAll()
.
β Dukungan
Dilanjutkan ...
Pembaca yang budiman! Sudahkah Anda menggunakan salah satu inovasi JavaScript yang dijelaskan di sini?
