Tambahan baru-baru ini
Ini adalah tambahan terbaru pada bahasa ini. Browser lama mungkin memerlukan polyfill.
Rangkaian opsional ?.
adalah cara aman untuk mengakses properti objek bersarang, meskipun properti perantara tidak ada.
Jika Anda baru saja mulai membaca tutorial dan mempelajari JavaScript, mungkin masalahnya belum menyentuh Anda, tetapi ini cukup umum.
Sebagai contoh, katakanlah kita mempunyai objek user
yang menyimpan informasi tentang pengguna kita.
Sebagian besar pengguna kami memiliki alamat di properti user.address
, dengan jalan user.address.street
, namun beberapa tidak menyediakannya.
Dalam kasus seperti ini, saat kami mencoba mendapatkan user.address.street
, dan pengguna tersebut kebetulan tidak memiliki alamat, kami mendapatkan kesalahan:
biarkan pengguna = {}; // pengguna tanpa properti "alamat". alert(pengguna.alamat.jalan); // Kesalahan!
Itulah hasil yang diharapkan. JavaScript bekerja seperti ini. Karena user.address
undefined
, upaya untuk mendapatkan user.address.street
gagal karena kesalahan.
Dalam banyak kasus praktis, kami lebih memilih untuk undefined
daripada error di sini (artinya “tidak ada jalan”).
…dan contoh lainnya. Dalam pengembangan Web, kita bisa mendapatkan objek yang sesuai dengan elemen halaman web menggunakan pemanggilan metode khusus, seperti document.querySelector('.elem')
, dan mengembalikan null
jika tidak ada elemen tersebut.
// document.querySelector('.elem') bernilai null jika tidak ada elemen biarkan html = document.querySelector('.elem').innerHTML; // error jika nol
Sekali lagi, jika elemennya tidak ada, kita akan mendapatkan kesalahan saat mengakses properti .innerHTML
dari null
. Dan dalam beberapa kasus, ketika tidak adanya elemen adalah hal yang normal, kami ingin menghindari kesalahan dan hanya menerima html = null
sebagai hasilnya.
Bagaimana kita bisa melakukan ini?
Solusi yang jelas adalah dengan memeriksa nilai menggunakan if
atau operator kondisional ?
, sebelum mengakses propertinya, seperti ini:
biarkan pengguna = {}; alert(pengguna.alamat ? pengguna.alamat.jalan : tidak terdefinisi);
Berhasil, tidak ada kesalahan… Tapi cukup janggal. Seperti yang Anda lihat, "user.address"
muncul dua kali dalam kode.
Berikut tampilan yang sama untuk document.querySelector
:
biarkan html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;
Kita dapat melihat bahwa elemen search document.querySelector('.elem')
sebenarnya dipanggil dua kali di sini. Tidak bagus.
Untuk properti yang bersarang lebih dalam, ini menjadi lebih buruk, karena diperlukan lebih banyak pengulangan.
Misalnya, mari kita dapatkan user.address.street.name
dengan cara yang sama.
biarkan pengguna = {}; // pengguna tidak memiliki alamat alert(alamat pengguna ? pengguna.alamat.jalan ? pengguna.alamat.jalan.nama : null : null);
Itu sangat buruk, seseorang bahkan mungkin mengalami masalah dalam memahami kode tersebut.
Ada cara yang lebih baik untuk menulisnya, menggunakan operator &&
:
biarkan pengguna = {}; // pengguna tidak memiliki alamat alert( alamat pengguna && alamat pengguna.jalan && alamat pengguna.nama jalan ); // tidak terdefinisi (tidak ada kesalahan)
DAN melakukan seluruh jalur ke properti memastikan bahwa semua komponen ada (jika tidak, evaluasi berhenti), tetapi juga tidak ideal.
Seperti yang Anda lihat, nama properti masih terduplikasi dalam kode. Misal pada kode di atas, user.address
muncul tiga kali.
Itu sebabnya rangkaian opsional ?.
telah ditambahkan ke bahasa. Untuk mengatasi masalah ini untuk selamanya!
Rangkaian opsional ?.
menghentikan evaluasi jika nilainya sebelumnya ?.
undefined
atau null
dan mengembalikan undefined
.
Lebih lanjut dalam artikel ini, untuk singkatnya, kami akan mengatakan bahwa sesuatu “ada” jika tidak null
dan tidak undefined
.
Dengan kata lain, value?.prop
:
berfungsi sebagai value.prop
, jika value
ada,
jika tidak (ketika value
undefined/null
) ia mengembalikan undefined
.
Berikut cara aman mengakses user.address.street
menggunakan ?.
:
biarkan pengguna = {}; // pengguna tidak memiliki alamat peringatan( pengguna?.alamat?.jalan ); // tidak terdefinisi (tidak ada kesalahan)
Kodenya pendek dan bersih, tidak ada duplikasi sama sekali.
Berikut ini contoh dengan document.querySelector
:
biarkan html = document.querySelector('.elem')?.innerHTML; // tidak akan terdefinisi, jika tidak ada elemen
Membaca alamat dengan user?.address
berfungsi meskipun objek user
tidak ada:
biarkan pengguna = null; peringatan( pengguna?.alamat ); // belum diartikan peringatan( pengguna?.alamat.jalan ); // belum diartikan
Harap dicatat: ?.
sintaks menjadikan nilai sebelumnya opsional, tetapi tidak lebih jauh.
Misal pada user?.address.street.name
the ?.
memungkinkan user
untuk dengan aman menjadi null/undefined
(dan mengembalikan undefined
dalam kasus itu), tetapi itu hanya untuk user
. Properti selanjutnya diakses dengan cara biasa. Jika kita ingin beberapa di antaranya bersifat opsional, maka kita perlu mengganti more .
dengan ?.
.
Jangan terlalu sering menggunakan rangkaian opsional
Kita harus menggunakan ?.
hanya jika tidak apa-apa kalau sesuatu itu tidak ada.
Misalnya, jika menurut logika kode kita objek user
harus ada, tetapi address
bersifat opsional, maka kita harus menulis user.address?.street
, tetapi tidak user?.address?.street
.
Kemudian, jika user
tidak terdefinisi, kita akan melihat kesalahan pemrograman dan memperbaikinya. Sebaliknya jika kita menggunakannya secara berlebihan ?.
, kesalahan pengkodean dapat dihilangkan jika tidak sesuai, dan menjadi lebih sulit untuk di-debug.
Variabel sebelumnya ?.
harus dideklarasikan
Jika tidak ada variabel user
sama sekali, maka user?.anything
akan memicu kesalahan:
//ReferenceError: pengguna tidak ditentukan pengguna?.alamat;
Variabel harus dideklarasikan (misalnya let/const/var user
atau sebagai parameter fungsi). Rangkaian opsional hanya berfungsi untuk variabel yang dideklarasikan.
Seperti yang dikatakan sebelumnya, ?.
segera menghentikan (“korsleting”) evaluasi jika bagian kiri tidak ada.
Jadi, apakah ada pemanggilan fungsi atau operasi lebih lanjut di sebelah kanan ?.
, itu tidak akan dibuat.
Misalnya:
biarkan pengguna = null; misalkan x = 0; pengguna?.sayHi(x++); // tidak ada "pengguna", sehingga eksekusi tidak mencapai panggilan sayHi dan x++ peringatan(x); // 0, nilai tidak bertambah
Rangkaian opsional ?.
bukan operator, melainkan konstruksi sintaksis khusus, yang juga berfungsi dengan fungsi dan tanda kurung siku.
Misalnya, ?.()
digunakan untuk memanggil fungsi yang mungkin tidak ada.
Pada kode di bawah ini, beberapa pengguna kami memiliki metode admin
, dan beberapa tidak:
biarkan admin pengguna = { admin() { peringatan("Saya Admin"); } }; biarkan penggunaGuest = {}; penggunaAdmin.admin?.(); // Saya adminnya penggunaGuest.admin?.(); // tidak ada yang terjadi (tidak ada metode seperti itu)
Di sini, di kedua baris pertama-tama kita menggunakan titik ( userAdmin.admin
) untuk mendapatkan properti admin
, karena kita berasumsi bahwa objek user
ada, sehingga aman untuk dibaca.
Kemudian ?.()
periksa bagian kiri: jika fungsi admin
ada, maka fungsi tersebut berjalan (begitu juga untuk userAdmin
). Jika tidak (untuk userGuest
) evaluasi akan berhenti tanpa kesalahan.
Sintaks ?.[]
juga berfungsi, jika kita ingin menggunakan tanda kurung []
untuk mengakses properti, bukan titik .
. Mirip dengan kasus sebelumnya, ini memungkinkan untuk membaca properti dengan aman dari objek yang mungkin tidak ada.
biarkan kunci = "Nama Depan"; biarkan pengguna1 = { Nama Depan: "John" }; biarkan pengguna2 = null; peringatan( pengguna1?.[kunci] ); // Yohanes peringatan( pengguna2?.[kunci] ); // belum diartikan
Kita juga bisa menggunakan ?.
dengan delete
:
hapus pengguna?.nama; // hapus nama pengguna jika pengguna ada
Kita bisa menggunakan ?.
untuk membaca dan menghapus dengan aman, tetapi tidak untuk menulis
Rangkaian opsional ?.
tidak ada gunanya di sisi kiri tugas.
Misalnya:
biarkan pengguna = null; pengguna?.nama = "John"; // Kesalahan, tidak berhasil // karena dievaluasi menjadi: undefinisi = "John"
Rangkaian opsional ?.
sintaks memiliki tiga bentuk:
obj?.prop
– mengembalikan obj.prop
jika obj
ada, jika tidak undefined
.
obj?.[prop]
– mengembalikan obj[prop]
jika obj
ada, jika tidak undefined
.
obj.method?.()
– memanggil obj.method()
jika obj.method
ada, jika tidak, kembalikan undefined
.
Seperti yang bisa kita lihat, semuanya mudah dan mudah digunakan. Itu ?.
memeriksa bagian kiri untuk null/undefined
dan memungkinkan evaluasi dilanjutkan jika tidak demikian.
Sebuah rantai ?.
memungkinkan untuk mengakses properti bersarang dengan aman.
Tetap saja, kita harus melamar ?.
hati-hati, hanya jika dapat diterima, menurut logika kode kita, bahwa bagian kiri tidak ada. Sehingga tidak menyembunyikan kesalahan pemrograman dari kami, jika itu terjadi.