Dalam JS sepertinya tidak mungkin untuk memeriksa apakah argumen yang dilewatkan ke suatu fungsi sebenarnya dari jenis 'kesalahan' atau contoh dari Kesalahan.
Misalnya, ini tidak valid:
typeof err === 'error'
karena hanya ada 6 jenis yang mungkin (dalam bentuk string):
Typeof operator mengembalikan informasi tipe sebagai string. Ada enam kemungkinan nilai yang typeof
mengembalikan:
"number", "string", "boolean", "object", "function" dan "undefined".
Tetapi bagaimana jika saya memiliki use case sederhana seperti ini:
function errorHandler(err) {
if (typeof err === 'error') {
throw err;
}
else {
console.error('Unexpectedly, no error was passed to error handler. But here is the message:',err);
}
}
jadi apa cara terbaik untuk menentukan apakah argumen adalah turunan dari Kesalahan?
adalah instanceof
operator bantuan?
javascript
node.js
Alexander Mills
sumber
sumber
err instanceof Error
err
memasukkan (katakanlah) iframe, tetapi kemudian meneruskannya ke jendela induk untuk diserahkan, Anda akan mendapatkannya(err instanceof Error) === false
. Itu karena iframe dan jendela induknya memilikiError
prototipe objek yang berbeda . Demikian pula objek sepertiobj = {};
kehendak, ketika diteruskan ke fungsi yang berjalan di jendela yang berbeda, yeild(obj instanceof Object)===false
. (Bahkan yang terburuk, di IE, jika Anda menyimpan referensi ke obj setelah jendelanya dihancurkan atau dinavigasi, mencoba memanggil prototipe objek fns sepertiobj.hasOwnProperty()
akan melempar kesalahan!)catch((err)=>{if (err === ENOENT)
mengembalikanENOENT is not defined
kesalahan?Jawaban:
Anda dapat menggunakan
instanceof
operator (tetapi lihat peringatan di bawah!).Di atas tidak akan berfungsi jika kesalahan dilemparkan ke jendela / bingkai / iframe yang berbeda dari tempat pemeriksaan terjadi. Dalam hal ini,
instanceof Error
cek akan mengembalikan false, bahkan untuk suatuError
objek. Dalam hal itu, pendekatan termudah adalah mengetik-bebek.Namun, pengetikan bebek dapat menghasilkan false positive jika Anda memiliki objek non-error yang berisi
stack
danmessage
properti.sumber
ReferenceError
instance. Anda sedang memeriksaReferenceError
objek global . Coba ini:try { foo } catch (e) { console.log(e instanceof Error) }
Logtrue
. Jika Anda mencoba memeriksaReferenceError
objek global karena beberapa alasan, Anda dapat menggunakanError.isPrototypeOf(ReferenceError)
ReferenceError
contoh bukan contohError
. Ini karena panggilan kevm.runInNewContext()
dalam simpul, di mana semua prototipe standar didefinisikan ulang. Semua hasil saya bukan contoh objek standar. Saya mencari di SO tentang hal ini, dan jatuh ke utas ini :)const error = (err instanceof Error || err instanceof TypeError) ? err : new Error(err.message ? err.message : err);
instanceof
jenis kesalahan khusus tho?Saya menanyakan pertanyaan asli - Jawaban @ Trott pasti yang terbaik.
Namun dengan JS sebagai bahasa yang dinamis dan dengan begitu banyak lingkungan runtime JS,
instanceof
operator dapat gagal terutama dalam pengembangan front-end ketika melintasi batas seperti iframe. Lihat: https://github.com/mrdoob/three.js/issues/5886Jika Anda baik-baik saja dengan mengetik bebek, ini seharusnya bagus:
Saya pribadi lebih suka bahasa yang diketik secara statis, tetapi jika Anda menggunakan bahasa yang dinamis, lebih baik merangkul bahasa yang dinamis dengan bahasa aslinya, daripada memaksanya berperilaku seperti bahasa yang diketik secara statis.
jika Anda ingin mendapatkan sedikit lebih tepat, Anda bisa melakukan ini:
sumber
instanceof
kegagalan operator dalam beberapa kasus, lihat artikel yang ditautkan.Error
,ReferenceError
, ...). Dan di lingkungan saya,instanceof
gagal total dalam banyak keadaan.Satu-satunya masalah dengan ini
Alternatif untuk ini adalah dengan menggunakan properti konstruktor.
Meskipun perlu dicatat bahwa kecocokan ini sangat spesifik, misalnya:
sumber
Anda dapat menggunakan
Object.prototype.toString
untuk dengan mudah memeriksa apakah suatu objek adalahError
, yang akan bekerja untuk bingkai yang berbeda juga.sumber
Anda dapat menggunakan obj.constructor.name untuk memeriksa "kelas" suatu objek https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes
Sebagai contoh
Baris di atas akan mencatat "Kesalahan" yang merupakan nama kelas objek. Ini dapat digunakan dengan kelas apa pun di javascript, jika kelas tersebut tidak menggunakan properti yang menggunakan nama "nama"
sumber
Terima kasih @ Trott untuk kode Anda, saya hanya menggunakan kode yang sama dan ditambahkan dengan contoh kerja waktu nyata untuk kepentingan orang lain.
sumber
Atau gunakan ini untuk berbagai jenis kesalahan
sumber