Pada bulan Juni 2018, standar ECMAScript 2015 (
ES6 ) merayakan peringatan tiga tahun. Dalam ES6, pertama, banyak fitur JavaScript baru telah muncul, dan kedua, era baru pengembangan bahasa dimulai dengan standar ini. Selain itu, ini adalah rilis JS berskala besar terakhir, karena sekarang TC39 menggunakan skema untuk menerbitkan masalah tahunan standar yang kecil, dan tidak mengeluarkannya lagi setiap beberapa tahun.

4 tahun terakhir, ES6, cukup dibenarkan, telah menarik perhatian universal. Penulis materi, terjemahan yang kami terbitkan hari ini, mengatakan bahwa selama ini, terima kasih kepada
Babel , ia menulis semua kode menggunakan versi modern dari spesifikasi JS. Dia percaya bahwa cukup waktu telah berlalu untuk menganalisis secara kritis fitur-fitur baru ES6. Secara khusus, dia tertarik pada apa yang dia gunakan untuk beberapa waktu, dan kemudian berhenti menggunakannya karena memperburuk kodenya.
Tentang kelemahan JS
Douglas Crockford, dalam
bukunya, JavaScript: Strengths, juga menulis tentang apa yang dapat dianggap sebagai kelemahan bahasa. Ini adalah sesuatu yang, menurutnya, tidak layak digunakan. Untungnya, di antara inovasi ES6 tidak ada yang tidak sedap dipandang seperti beberapa fitur bermasalah lama JS, seperti operator kesetaraan lemah yang melakukan konversi tipe implisit, fungsi
eval()
, dan pernyataan
with
. Fitur-fitur baru ES6 dirancang jauh lebih baik. Namun, ada beberapa hal dalam dirinya yang saya hindari. Fitur-fitur yang ada dalam daftar "kelemahan" JS saya ada di daftar ini karena alasan berikut:
- Mereka pada dasarnya adalah "jebakan". Artinya, tampaknya mereka dirancang untuk melakukan tindakan tertentu, dan dalam kebanyakan kasus, mereka berfungsi seperti yang diharapkan. Namun, terkadang mereka berperilaku tidak terduga, yang dengan mudah dapat menyebabkan kesalahan.
- Mereka meningkatkan volume bahasa dengan imbalan manfaat kecil. Peluang semacam itu memberi pengembang beberapa keuntungan kecil, tetapi membutuhkan seseorang yang mencoba mencari tahu kodenya untuk memiliki pengetahuan tentang mekanisme tertentu, biasanya tersembunyi di suatu tempat. Ini berlaku ganda untuk kemampuan API, ketika menggunakan fitur ini berarti bahwa kode lain yang berinteraksi dengan kode yang ditulis oleh pengembang tertentu harus mengetahui penerapan fitur API ini.
Sekarang, dipandu oleh pertimbangan ini, mari kita bicara tentang kelemahan ES6.
Kata kunci const
Sebelum ES6, variabel dalam JavaScript dapat dideklarasikan menggunakan kata kunci
var
. Selain itu, variabel tidak dapat dideklarasikan sama sekali, maka mereka, bahkan jika digunakan dalam fungsi, termasuk dalam ruang lingkup global. Properti objek dapat memainkan peran variabel, dan fungsi dideklarasikan menggunakan
function
kata kunci. Kata kunci
var
memiliki fitur tertentu.
Jadi, ini memungkinkan Anda untuk membuat variabel yang ditambahkan ke objek global, atau yang lingkupnya dibatasi oleh fungsi. Namun, kata kunci
var
tidak memperhatikan blok kode. Selain itu, Anda dapat merujuk ke variabel yang dideklarasikan menggunakan kata kunci
var
dalam kode yang terletak sebelum perintah untuk deklarasi. Fenomena ini dikenal sebagai menaikkan variabel. Fitur-fitur ini, jika tidak diperhitungkan, dapat menyebabkan kesalahan. Untuk memperbaiki situasi, ES6 memperkenalkan dua kata kunci baru untuk mendeklarasikan variabel:
let
dan
const
. Mereka memecahkan masalah utama
var
. Yaitu, kita berbicara tentang fakta bahwa variabel yang dideklarasikan menggunakan kata kunci ini memiliki cakupan blok, sebagai akibatnya, sebagai contoh, variabel yang dideklarasikan dalam satu lingkaran tidak terlihat di luarnya. Selain itu, menggunakan
let
dan
const
tidak memungkinkan variabel diakses sebelum mereka dideklarasikan. Ini akan menghasilkan kesalahan
ReferenceError
. Ini adalah langkah besar ke depan. Namun, munculnya dua kata kunci baru, serta fitur-fiturnya, menyebabkan kebingungan tambahan.
Nilai variabel (konstan) yang dinyatakan menggunakan kata kunci
const
tidak dapat ditimpa setelah deklarasi. Ini adalah satu-satunya perbedaan antara
const
dan
let
. Peluang baru ini terlihat bermanfaat, dan benar-benar dapat membawa manfaat. Masalahnya adalah kata kunci
const
itu sendiri. Cara konstanta yang dinyatakan menggunakannya berperilaku tidak sesuai dengan apa yang diasosiasikan sebagian besar pengembang dengan konsep "konstan".
const CONSTANT = 123; // "TypeError: invalid assignment to const `CONSTANT`" CONSTANT = 345; const CONSTANT_ARR = [] CONSTANT_ARR.push(1) // [1] - console.log(CONSTANT_ARR)
Menggunakan kata kunci
const
mencegah nilai baru ditulis ke konstanta, tetapi tidak membuat objek yang direferensikan oleh konstanta seperti tidak dapat diubah. Fitur ini memberikan perlindungan yang buruk terhadap perubahan nilai saat bekerja dengan sebagian besar tipe data. Akibatnya, karena fakta bahwa menggunakan
const
dapat menyebabkan kebingungan, dan karena fakta bahwa jika kata kunci
let
hadir, keberadaan
const
terlihat berlebihan, saya memutuskan untuk selalu menggunakan
let
.
String Templat Tagged
Kata kunci
const
adalah contoh bagaimana spesifikasi menciptakan terlalu banyak cara untuk menyelesaikan terlalu sedikit masalah. Dalam hal string templat yang ditandai, kami memiliki situasi sebaliknya. Sintaksis string semacam itu dianggap oleh komite TC39 sebagai cara untuk menyelesaikan interpolasi string dan string multiline. Kemudian mereka memutuskan untuk memperluas kesempatan ini melalui penggunaan makro.
Jika Anda belum pernah melihat string pola yang ditandai sebelumnya, perlu diingat bahwa mereka sedikit seperti
dekorator string. Berikut adalah contoh bekerja dengan mereka dengan
MDN :
var person = 'Mike'; var age = 28; function myTag(strings, personExp, ageExp) { var str0 = strings[0]; // "that " var str1 = strings[1]; // " is a " // ( ) // , // , . // var str2 = strings[2]; var ageStr; if (ageExp > 99){ ageStr = 'centenarian'; } else { ageStr = 'youngster'; } return str0 + personExp + str1 + ageStr; } var output = myTag`that ${ person } is a ${ age }`; console.log(output); // that Mike is a youngster
String template yang ditandai tidak dapat disebut tidak berguna sama sekali. Berikut ini adalah
ikhtisar dari beberapa kegunaannya. Misalnya, mereka berguna dalam membersihkan kode HTML. Dan, saat ini, aplikasi mereka menunjukkan pendekatan yang paling akurat dalam situasi ketika Anda perlu melakukan operasi yang sama pada semua data input dari templat string yang arbitrer. Namun, ini relatif jarang terjadi, Anda dapat melakukan hal yang sama menggunakan API yang sesuai (meskipun solusi seperti itu lebih lama). Dan, untuk mengatasi sebagian besar masalah, menggunakan API tidak akan lebih buruk daripada menggunakan string templat yang ditandai. Fitur ini tidak menambahkan fitur baru ke bahasa. Dia menambahkan pendekatan baru untuk bekerja dengan data yang seharusnya tidak asing bagi mereka yang harus membaca kode yang ditulis menggunakan string templat yang ditandai. Dan saya berusaha untuk memastikan bahwa kode saya tetap sebersih dan semudah mungkin dimengerti.
Ekspresi Penugasan Destructive Redesigned
Beberapa fitur bahasa tampak hebat ketika digunakan untuk menyelesaikan tugas-tugas sederhana, namun, ketika tugas menjadi lebih kompleks, fitur-fitur ini bisa lepas kendali. Sebagai contoh, saya suka operator kondisional ternary:
let conferenceCost = isStudent ? 50 : 200
Namun, kode yang ditulis dengan bantuannya, menjadi sulit untuk dipahami jika, menggunakan operator ini, Anda mulai menggunakan konstruksi bersarang:
let conferenceCost = isStudent ? hasDiscountCode ? 25 : 50 : hasDiscountCode ? 100 : 200;
Hal yang sama dapat dikatakan tentang penugasan destruktif. Mekanisme ini memungkinkan Anda untuk menarik nilai variabel dari objek atau array:
let {a} = {a: 2, b: 3}; let [b] = [4, 5]; console.log(a, b)
Selain itu, saat menggunakannya, Anda dapat mengubah nama variabel, mendapatkan nilai bersarang, mengatur nilai default:
let {a: val1} = {a: 2, b: 3}; let [{b}] = [{a:3, b:4} , {c: 5, d: 6}]; let {c=6} = {a: 2, c: 5}; let {d=6} = {a: 2, c: 5}; console.log(val1, b, c, d)
Semua ini luar biasa - sampai sampai pada membangun ekspresi kompleks menggunakan semua fitur ini. Misalnya, dalam ekspresi di bawah ini, 4 variabel dinyatakan:
userName
,
eventType
,
eventDate
, dan
eventId
. Nilai-nilai mereka diambil dari tempat yang berbeda dalam struktur objek
eventRecord
.
let eventRecord = { user: { name: "Ben M", email: "ben@m.com" }, event: "logged in", metadata: { date: "10-10-2017" }, id: "123" }; let { user: { name: userName = "Unknown" }, event: eventType = "Unknown Event", metadata: [date: eventDate], id: eventId } = obj;
Memahami kode semacam itu hampir tidak mungkin. Masalah ini dapat diselesaikan dengan menggunakan kode yang lebih mudah dibaca, jika Anda menggunakan beberapa operasi perusakan atau benar-benar meninggalkannya.
let eventRecord = { user: { name: "Ben M", email: "ben@m.com" }, event: "logged in", metadata: { date: "10-10-2017" }, id: "123" }; let userName = eventRecord.user.userName || 'Unknown'; let eventDate = eventRecord.metadata.date; let {event:eventType='UnknownEvent', id:eventId} = eventRecord;
Saya tidak memiliki pedoman yang jelas yang menunjukkan bahwa ekspresi tugas destruktif perlu dikerjakan ulang. Namun, setiap kali saya melihat ekspresi yang sama dan tidak dapat langsung memahami masalah apa yang dipecahkannya, variabel apa yang digunakan di dalamnya, saya mengerti bahwa inilah saatnya untuk menyederhanakan kode untuk meningkatkan keterbacaannya.
Ekspor default
ES6 memiliki satu fitur yang bagus. Ini terdiri dari bagaimana pengembangnya mendekati standardisasi dari apa yang sebelumnya dilakukan dengan bantuan berbagai perpustakaan, seringkali saling bersaing. Jadi dalam spesifikasi muncul kelas, janji, modul. Ini semua yang digunakan komunitas pengembang JS sebelum ES6, menemukannya di perpustakaan pihak ketiga. Sebagai contoh, modul ES6 adalah pengganti yang sangat baik untuk apa yang tumpah ke dalam perang format AMD / CommonJS dan memberikan sintaksis yang mudah untuk mengatur impor.
Modul ES6 mendukung dua cara utama untuk mengekspor nilai: ekspor bernama dan ekspor default, atau ekspor standar:
const mainValue = 'This is the default export export default mainValue export const secondaryValue = 'This is a secondary value; export const secondaryValue2 = 'This is another secondary value;
Modul dapat menggunakan beberapa perintah ekspor bernama, tetapi hanya satu perintah ekspor default. Saat mengimpor apa yang diekspor menggunakan perintah ekspor default, dalam file impor, Anda dapat memberikan apa pun yang diekspor secara default nama apa pun, karena tidak ada nama yang dicari selama operasi ini. Saat menggunakan ekspor bernama, Anda perlu menggunakan nama variabel dari file yang diekspor, meskipun penggantian nama juga dimungkinkan.
// import renamedMainValue from './the-above-example'; // import {secondaryValue} from './the-above-example'; // import {secondaryValue as otherValue} from './the-above-example';
Ekspor default menikmati
perhatian khusus dari pengembang standar ES6, dan mereka sengaja membuat sintaksis yang lebih sederhana untuk itu. Namun, dalam praktiknya, saya dapat mengetahui bahwa menggunakan teknologi ekspor yang dinamai lebih disukai karena alasan berikut.
- Saat menggunakan ekspor bernama, nama-nama variabel yang diekspor, secara default, sesuai dengan nama-nama variabel yang diimpor, yang menyederhanakan pencarian mereka bagi mereka yang tidak menggunakan alat pengembangan cerdas.
- Saat menggunakan ekspor bernama, programmer yang menggunakan alat pengembangan pintar mendapatkan fitur nyaman seperti impor otomatis .
- Ekspor bernama memungkinkan Anda untuk mengekspor seragam dari modul apa pun yang Anda inginkan, dalam jumlah yang tepat. Ekspor default membatasi pengembang untuk hanya mengekspor nilai tunggal. Sebagai solusinya, Anda bisa menerapkan ekspor objek dengan beberapa properti. Namun, pendekatan ini kehilangan nilai algoritma pengocok pohon yang digunakan untuk mengurangi ukuran aplikasi JS yang dibangun oleh sesuatu seperti webpack. Menggunakan modul yang diberi nama secara eksklusif menyederhanakan pekerjaan.
Secara umum, dapat dicatat bahwa entitas penamaan adalah praktik yang baik, karena memungkinkan Anda untuk mengidentifikasi mereka secara unik dalam kode dan dalam percakapan tentang kode ini. Itu sebabnya saya menggunakan ekspor bernama.
Ringkasan
Anda baru saja belajar tentang fitur ES6, yang, menurut penulis materi ini, tidak berhasil. Mungkin Anda bergabung dengan pendapat ini, mungkin juga tidak. Bahasa pemrograman apa pun adalah sistem yang kompleks, yang kemampuannya dapat dilihat dari berbagai sudut pandang. Namun, kami berharap artikel ini bermanfaat bagi semua yang berusaha menulis kode yang jelas dan berkualitas tinggi.
Pembaca yang budiman! Adakah sesuatu dalam JavaScript modern yang Anda coba hindari?
