Saya baru -baru ini menulis tentang fitur baru yang diperkenalkan di ES2020... Meskipun beberapa dari peluang ini menarik, tidak ada satu pun yang pantas disebut "revolusioner". Hal ini dapat dimengerti mengingat fakta bahwa spesifikasi JS cukup sering diperbarui belakangan ini. Ternyata mereka yang mengerjakan standar hanya memiliki sedikit kesempatan untuk terus-menerus memperkenalkan sesuatu yang istimewa ke dalam bahasa tersebut, seperti modul ES6 atau fungsi panah. Tetapi ini tidak berarti bahwa sesuatu yang eksklusif baru pada akhirnya tidak akan muncul dalam bahasa tersebut. Faktanya, inilah yang ingin saya bicarakan hari ini. Saya ingin berbicara tentang 4 kemungkinan yang, di masa depan, bisa disebut revolusioner. Mereka sekarang berada pada tahapan proses yang berbeda.
koordinasi proposal. Ini, di satu sisi, berarti bahwa kita mungkin tidak pernah melihatnya di JavaScript dan tidak melihatnya, dan di sisi lain, kehadiran kalimat seperti itu memberi kita harapan bahwa kita akan, bagaimanapun, suatu saat akan bertemu mereka dalam bahasa tersebut.
Dekorator
Kami akan mulai dengan fitur yang mungkin paling sering diminta untuk disertakan dalam bahasa ini, dan di sekitarnya cukup banyak desas-desus yang diangkat. Beberapa tahun yang lalu, mereka menulis tentang dia di mana-mana. Ini tentang dekorator .
Anda mungkin sudah tidak asing lagi dengan dekorator. Terutama jika Anda menulis di TypeScript. Pada dasarnya, ini adalah konsep metaprogramming yang bertujuan memberi pengembang kemampuan untuk "memasukkan" fungsionalitas mereka sendiri ke dalam kelas, ke dalam bidang dan metode masing-masing, yang pada akhirnya membuat kelas dapat diprogram.
Lihat contoh berikut:
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;
}
}
Di sini saya memutuskan untuk melanjutkan dengan hati-hati dan memberikan contoh penggunaan dekorator TypeScript . Saya melakukan ini terutama untuk menunjukkan gagasan umum. Dalam potongan kode di atas, kami membuat dekorator
sealed
dan menerapkannya ke kelas Greeter
. Seperti yang bisa Anda lihat dengan mudah, dekorator hanyalah sebuah fungsi yang memiliki akses ke konstruktor kelas yang diterapkan (ini adalah targetnya). Kami menggunakan referensi ke konstruktor, serta metode Object.seal()
untuk membuat kelas tidak dapat diperluas.
Untuk menerapkan dekorator ke kelas, kita menulis nama dekorator dengan ikon
@
tepat sebelum deklarasi kelas. Akibatnya, ternyata sebelum deklarasi kelas muncul konstruksi formulir @[name]
, yang dalam kasus kami terlihat seperti @sealed
.
Anda dapat memeriksa fungsionalitas dekorator dengan menyusun kode TS ini dengan opsi diaktifkan
experimentalDecorators
dan mencoba mengubah prototipe kelas:
Greeter.prototype.test = "test"; // ERROR
Akibatnya, Anda sekarang harus memiliki pemahaman umum tentang mengapa dekorator dibutuhkan sama sekali. Tetapi saya ingin menyentuh satu pertanyaan yang sulit di sini. Ini menyangkut status persetujuan proposal untuk dekorator.
Saya memutuskan untuk menggunakan TypeScript untuk mendemonstrasikan dekorator untuk alasan yang bagus. Intinya adalah proposal untuk menyematkan dekorator di JavaScript sudah ada beberapa tahun yang lalu. Dan sekarang "hanya" pada tahap ke-2 dari persetujuan 4. Baik sintaksis maupun kemampuan dekorator dari proposal ini terus berubah. Namun itu tidak menghentikan komunitas JS untuk menggunakan konsep ini. Untuk diyakinkan tentang ini, cukup melihat proyek open source besar seperti TypeScript atau Angular v2 +.
Benar, semua ini, dari waktu ke waktu, dan seiring berkembangnya proposal, mengarah pada masalah yang terkait dengan ketidakcocokan spesifikasi. Yakni, spesifikasi dekorator sudah banyak berkembang sejak proposal dibuat, namun banyak proyek yang masih belum mengimplementasikannya. Contoh TypeScript yang ditunjukkan di atas adalah demonstrasi penerapan versi proposal yang lebih lama. Hal yang sama dapat dikatakan untuk Angular, dan bahkan Babel (meskipun, dalam kasus Babel, kita dapat mengatakan bahwa pekerjaan sedang dilakukan untuk mengimplementasikan versi yang lebih baru dari spesifikasi ini). Secara umum, versi kalimat yang lebih baru, yang menggunakan kata kunci
decorator
dan sintaksis yang sesuai untuk penautan, belum menemukan penggunaan yang nyata.
Intinya adalah bahwa dekorator memiliki potensi untuk mengubah cara kita menulis kode. Dan perubahan tersebut sudah terlihat dengan sendirinya, meski dekorator masih dalam tahap awal. Namun, mengingat keadaan saat ini, dekorator hanya memecah komunitas, dan saya yakin mereka belum siap untuk digunakan secara serius. Saya akan menyarankan mereka yang tertarik dengan dekorator untuk menunggu sebentar sebelum memperkenalkan mereka ke dalam produksi. Rekomendasi saya, bagaimanapun, tidak berlaku untuk mereka yang menggunakan kerangka kerja yang menggunakan dekorator (seperti Angular).
Alam
Sekarang mari kita memperlambat sedikit dan berbicara tentang satu fitur yang tidak serumit dekorator. Kami berbicara tentang area .
Anda mungkin pernah berada dalam situasi di mana Anda perlu menjalankan kode Anda sendiri, atau kode pihak ketiga, tetapi pada saat yang sama melakukannya sedemikian rupa sehingga kode ini tidak akan memengaruhi lingkungan global. Banyak pustaka, terutama yang peramban, bekerja melalui objek global
window
. Akibatnya, mereka dapat saling mengganggu jika proyek menggunakan terlalu banyak pustaka di luar kendali pengembang. Ini dapat menyebabkan kesalahan.
Solusi browser saat ini untuk masalah ini adalah dengan menggunakan elemen
<iframe>
, dan dalam beberapa kasus khusus - dalam penggunaan pekerja web. Di lingkungan Node.js, masalah yang sama diselesaikan menggunakan modul vm
atau menggunakan proses anak . Realms API dirancang untuk mengatasi masalah tersebut.
API ini bertujuan untuk memungkinkan pengembang membuat lingkungan global terpisah yang disebut cakupan. Setiap wilayah memiliki entitas globalnya sendiri. Lihat contoh berikut:
var x = 39;
const realm = new Realm();
realm.globalThis.x; // undefined
realm.globalThis.x = 42; // 42
realm.globalThis.x; // 42
x; // 39
Di sini kita membuat objek baru
Realm
menggunakan konstruktor yang sesuai. Mulai sekarang, kami memiliki akses penuh ke cakupan baru dan objek globalnya melalui properti globalThis
(diperkenalkan di ES2020). Di sini Anda dapat melihat bahwa variabel "inkubator" utama dipisahkan dari variabel dalam lingkup yang kita buat.
Secara keseluruhan, Realms API direncanakan sebagai mekanisme yang sangat sederhana, tetapi ini adalah mekanisme yang berguna. API ini memiliki sekumpulan kasus penggunaan yang sangat spesifik. Itu tidak memberi kita tingkat keamanan yang lebih tinggi, atau kemampuan untuk membuat kode multithread. Tetapi dengan sempurna, tanpa membuat beban yang tidak perlu pada sistem, mengatasi tugas utamanya, dengan menyediakan kemampuan dasar untuk menciptakan lingkungan yang terisolasi.
Proposal Realms API saat ini sedang dalam negosiasi tahap 2. Ketika akhirnya mencapai standar, orang akan mengharapkannya untuk digunakan di perpustakaan "berat" yang bergantung pada cakupan global, di editor kode kotak pasir online, dalam berbagai aplikasi yang menargetkan pengujian.
Lakukan ekspresi
Sintaks JavaScript, seperti sintaks kebanyakan bahasa pemrograman, menyertakan pernyataan dan ekspresi. Perbedaan paling mencolok antara konstruksi ini adalah bahwa ekspresi dapat digunakan sebagai nilai (yaitu, ekspresi dapat ditempatkan ke variabel, diteruskan ke fungsi, dan seterusnya), sementara pernyataan tidak dapat digunakan seperti itu.
Karena perbedaan ini, ekspresi adalah pilihan paling disukai untuk menulis kode yang lebih rapi dan ringkas. Dalam JavaScript, Anda dapat melihatnya dengan melihat popularitas ekspresi fungsi, yang mencakup fungsi panah, versus deklarasi fungsi, pernyataan fungsi. Situasi yang sama terlihat jika kita membandingkan metode untuk iterasi melalui array (seperti
forEach()
) dengan siklus. Hal yang sama berlaku untuk programmer yang lebih mahir saat membandingkan operator terner dan pernyataan if
.
Proposal do-expression , yang saat ini sedang dalam tahap negosiasi 1, bertujuan untuk lebih meningkatkan kapabilitas ekspresi JS. Dan, omong-omong, jangan bingung dengan konsep "lakukan-ekspresi" dengan loop
doโฆwhile
, karena keduanya sama sekali berbeda.
Berikut contohnya:
let x = do {
if (foo()) {
f();
} else if (bar()) {
g();
} else {
h();
}
};
Berikut sintaks dari klausa do-expression. Secara umum, kita memiliki sebelum kita sepotong kode JS yang dibungkus dalam sebuah konstruksi
do {}
. Ekspresi terakhir dalam konstruksi ini "dikembalikan" sebagai nilai akhir dari keseluruhan ekspresi do.
Efek serupa (tapi tidak identik) dapat dicapai dengan menggunakan IIFE (Ekspresi Fungsi Segera Diminta). Namun dalam kasus ekspresi do, sintaksis kompaknya tampak sangat menarik. Di sini, dengan fungsionalitas serupa, Anda tidak memerlukan salah satunya
return
, atau struktur tambahan yang jelek seperti(() => {})()
... Inilah mengapa saya percaya bahwa begitu ekspresi masuk ke standar, dampaknya pada JavaScript akan sebanding dengan fungsi panah. Kemudahan berekspresi dan sintaksis yang bersahabat, bisa dibilang, dalam satu paket, terlihat sangat menggoda.
Pencocokan pola
Kesempatan ini adalah yang terakhir dalam materi ini, tetapi ini jauh dari kepentingan terakhir. Ini adalah proposal yang bertujuan untuk memperkenalkan mekanisme pencocokan pola ke dalam bahasa .
Anda mungkin sudah familiar dengan instruksi JS
switch
. Mirip dengan if-else
, tetapi opsinya sedikit lebih terbatas, dan tentunya lebih cocok untuk mengatur pilihan salah satu dari banyak alternatif. Beginilah tampilannya:
switch (value) {
case 1:
// ...
break;
case 2:
// ...
break;
case 3:
// ...
break;
default:
// ...
break;
}
Secara pribadi, saya pikir sebuah instruksi
switch
lebih lemah daripada sebuah instruksi if
, karena switch
dapat membandingkan apa yang diteruskan kepadanya hanya dengan nilai-nilai tertentu. Batasan ini dapat dielakkan , tetapi saya tidak dapat memikirkan mengapa. Selain itu, instruksi switch
dibebani dengan elemen tambahan. Secara khusus, kita berbicara tentang instruksi break
.
Mekanisme pencocokan pola dapat dianggap sebagai versi pernyataan yang lebih fungsional, berbasis ekspresi, dan berpotensi lebih serbaguna
switch
. Daripada hanya membandingkan nilai, mekanisme pencocokan pola memungkinkan pengembang membandingkan nilai dengan pola khusus (templat) yang sangat dapat disesuaikan. Berikut ini potongan kode yang menunjukkan contoh dari API yang diusulkan:
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})
Ia menggunakan sintaks yang tidak biasa untuk JavaScript (meskipun didasarkan pada sintaks yang ditemukan dalam bahasa seperti Rust atau Scala ), yang memiliki beberapa kesamaan dengan instruksi yang sudah kita kenal
switch
. Di sini, alih-alih kata kunci, switch
digunakan kata case
yang menandai awal blok di mana nilainya dicentang. Kemudian, di dalam blok tersebut, menggunakan kata kunciwhen
, kami menjelaskan templat yang ingin kami validasi nilainya. Sintaks templat menyerupai sintaksis mekanisme perusakan objek yang sudah tersedia dalam bahasa tersebut. Anda dapat membandingkan nilai dengan objek yang berisi properti yang dipilih, Anda dapat membandingkannya dengan nilai properti pada objek, dan banyak entitas lainnya. Untuk mempelajari lebih lanjut tentang mekanisme ini - lihat dokumen ini .
Setelah deskripsi template, ada panah ("panah datar",
->
) yang menunjuk ke ekspresi (dalam perspektif - bahkan ke nilai yang berbeda), yang harus dievaluasi saat menemukan kecocokan dengan pola.
Saya percaya bahwa kehadiran kemampuan seperti itu di JS akan memungkinkan kita untuk menulis, bisa dikatakan, kode generasi baru. Namun, sintaks yang diusulkan sekarang tampaknya agak merepotkan bagi saya, karena ini memperkenalkan banyak konstruksi yang benar-benar baru ke dalam bahasa. Dan fakta bahwa proposal ini masih dalam tahap kesepakatan pertama membuat saya berpikir bahwa masih ada ruang untuk perbaikan. Fitur ini terlihat sangat menjanjikan, namun masih memiliki jalan panjang sebelum berhasil masuk ke spesifikasi JS resmi.
Hasil
Ini menyimpulkan cerita saya tentang fitur revolusioner dari JavaScript, yang, mungkin, akan kita lihat dalam bahasanya di masa mendatang. Ada kemungkinan serupa lainnya, misalnya, proposal untuk pustaka standar eksternal dan operator pipelined . Tetapi saya memilih materi ini hanya yang menurut saya paling menarik. Perlu diingat bahwa peluang ini masih dalam tahap proposal. Mereka bisa berubah seiring waktu. Atau mungkin saja mereka tidak pernah masuk ke standar. Tetapi jika Anda, bagaimanapun, ingin berada di antara mereka yang menggunakan peluang seperti itu sebelum orang lain, saya menyarankan Anda untuk melihat lebih dekat proyek-proyek seperti Babel.... Proyek-proyek ini melahirkan banyak kalimat JS (terutama yang terkait dengan sintaks). Ini memungkinkan siapa saja untuk bereksperimen dengan fitur terbaru jauh sebelum fitur tersebut muncul dalam implementasi bahasa.
Fitur apa yang paling Anda lewatkan di JavaScript?