Dalam kode saya, saya berurusan dengan array yang memiliki beberapa entri dengan banyak objek bersarang di dalam satu sama lain, sedangkan beberapa tidak. Ini terlihat seperti berikut:
// where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];
Ini memberi saya masalah karena saya kadang-kadang perlu mengulang melalui array, dan ketidakkonsistenan membuat saya mengalami kesalahan seperti:
for (i=0; i<test.length; i++) {
// ok on i==0, but 'cannot read property of undefined' on i==1
console.log(a.b.c);
}
Saya sadar bahwa saya dapat mengatakannya if(a.b){ console.log(a.b.c)}
, tetapi ini sangat membosankan jika terdapat hingga 5 atau 6 objek yang bersarang satu sama lain. Apakah ada cara lain (lebih mudah) yang saya dapat memilikinya HANYA melakukan console.log jika ada, tetapi tanpa menimbulkan kesalahan?
javascript
Ari
sumber
sumber
try..catch
pernyataannya. Meskipun demikian, array yang berisi elemen heterogen yang liar terlihat seperti masalah desain bagi saya.if ("b" in a && "c" in a.b)
. Ini mungkin "membosankan", tapi itulah yang Anda dapatkan dari ketidakkonsistenan ... logika normal.Jawaban:
Pembaruan :
Solusi untuk JavaScript sebelum ECMASCript 2020 atau TypeScript lebih lama dari versi 3.7 :
Solusi cepat adalah menggunakan fungsi pembantu coba / tangkap dengan fungsi panah ES6 :
Cuplikan kerja:
Tampilkan cuplikan kode
Lihat artikel ini untuk detailnya.
sumber
Apa yang Anda lakukan menimbulkan pengecualian (dan memang seharusnya demikian).
Anda selalu bisa melakukannya
Tapi saya tidak akan, sebaliknya memikirkan kasus penggunaan Anda.
Mengapa Anda mengakses data, 6 level bersarang yang tidak Anda kenal? Kasus penggunaan apa yang membenarkan hal ini?
Biasanya, Anda ingin benar-benar memvalidasi jenis objek yang Anda hadapi.
Selain itu, di samping catatan Anda tidak boleh menggunakan pernyataan seperti
if(a.b)
karena akan mengembalikan false jika ab adalah 0 atau bahkan jika itu adalah "0". Sebaliknya, periksa apakaha.b !== undefined
sumber
typeof a.b === "undefined" && a.b!=null
- tidak perlu melakukan bagian kedua setelah yang pertama, dan lebih masuk akal untuk melakukannyaif ("b" in a)
typeof a.b !
== "undefined" && ab! = Null` - perhatikan!==
Jika saya memahami pertanyaan Anda dengan benar, Anda menginginkan cara teraman untuk menentukan apakah suatu objek mengandung properti.
Cara termudah adalah dengan menggunakan
in
operator .Tentu saja Anda bisa mengumpulkan ini sedalam yang Anda inginkan
Tidak yakin apakah ini membantu.
sumber
window.b
tidak ditentukan? Anda akan mendapatkan kesalahan tipe:Cannot use 'in' operator to search for 'c' in undefined
Jika Anda menggunakan lodash , Anda dapat menggunakan fungsi "has" mereka. Ini mirip dengan "dalam" asli, tetapi memungkinkan jalur.
sumber
_.get()
dengan default agar mudah dibaca:_.get(object, 'a.b.c', 'default');
Coba ini. Jika
a.b
tidak ditentukan, itu akan meninggalkanif
pernyataan tanpa terkecuali.sumber
Ini adalah masalah umum ketika bekerja dengan objek json yang dalam atau kompleks, jadi saya mencoba untuk menghindari mencoba / menangkap atau menyematkan beberapa pemeriksaan yang akan membuat kode tidak dapat dibaca, saya biasanya menggunakan potongan kode kecil ini di semua proses saya untuk melakukan pekerjaan itu.
sumber
Jika Anda memiliki lodash, Anda dapat menggunakan
.get
metodenyaatau berikan nilai default
sumber
Saya menggunakan undefsafe secara religius. Ini menguji setiap level ke dalam objek Anda sampai mendapatkan nilai yang Anda minta, atau mengembalikan "tidak ditentukan". Tapi tidak pernah ada kesalahan.
sumber
_.get
Jika Anda menggunakan Babel, Anda sudah dapat menggunakan sintaks rantai opsional dengan plugin Babel @ babel / plugin-proposal-optional-chaining . Ini akan memungkinkan Anda untuk mengganti ini:
dengan ini:
sumber
Saya suka jawaban Cao Shouguang, tetapi saya tidak suka melewatkan fungsi sebagai parameter ke dalam fungsi getSafe setiap kali saya melakukan panggilan. Saya telah memodifikasi fungsi getSafe untuk menerima parameter sederhana dan ES5 murni.
sumber
getSafe(myObj.x.c)
. Sudah mencoba versi terbaru Chrome dan Firefox.Dalam jawaban str, nilai 'undefined' akan dikembalikan alih-alih nilai default yang ditetapkan jika properti tidak ditentukan. Ini terkadang dapat menyebabkan bug. Berikut ini akan memastikan defaultVal akan selalu dikembalikan jika properti atau objek tidak ditentukan.
sumber
Lodash memiliki
get
metode yang memungkinkan default sebagai parameter ketiga opsional, seperti yang ditunjukkan di bawah ini:sumber
Bayangkan kita ingin menerapkan serangkaian fungsi ke
x
jika dan hanya jikax
bukan nol:Sekarang katakanlah kita perlu melakukan hal yang sama untuk
y
:Dan sama untuk
z
:Seperti yang Anda lihat tanpa abstraksi yang tepat, kami akan menggandakan kode berulang kali. Abstraksi seperti itu sudah ada: monad Maybe .
The Mungkin monad memegang kedua nilai dan konteks komputasi:
Penerapan yang naif akan terlihat seperti ini:
⚠️ Penerapan ini hanya untuk tujuan ilustrasi! Ini bukanlah bagaimana seharusnya dilakukan dan salah di banyak tingkatan. Namun ini akan memberi Anda gambaran yang lebih baik tentang apa yang saya bicarakan.
Seperti yang Anda lihat, tidak ada yang bisa pecah:
Lampiran 1
Saya tidak dapat menjelaskan apa itu monad karena ini bukan tujuan dari posting ini dan ada orang di luar sana yang lebih baik daripada saya. Namun seperti yang dikatakan Eric Elliot dalam posting blog sebelumnya, JavaScript Monads Made Simple :
Lampiran 2
Inilah cara saya menyelesaikan masalah Anda menggunakan Mungkin monad frommonetjs
sumber
Saya menjawab ini sebelumnya dan kebetulan melakukan pemeriksaan serupa hari ini. Penyederhanaan untuk memeriksa apakah ada properti bertitik bertingkat. Anda dapat mengubah ini untuk mengembalikan nilai, atau beberapa default untuk mencapai tujuan Anda.
Dalam pertanyaan Anda, Anda dapat melakukan sesuatu seperti:
sumber
Saya biasanya menggunakan seperti ini:
sumber
Anda dapat menghindari kesalahan dengan memberikan nilai default sebelum mendapatkan properti
Ini berfungsi baik dengan array juga:
sumber