Untuk beberapa alasan, sepertinya delegasi konstruktor tidak berfungsi dalam cuplikan berikut:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
Menjalankan ini memberi The message is: ''
. Adakah ide mengapa, atau jika ada cara yang lebih baik untuk membuat Error
subkelas baru ? Apakah ada masalah dengan konstruktor apply
asli Error
yang saya tidak tahu?
javascript
exception
cdleary
sumber
sumber
Jawaban:
Perbarui kode Anda untuk menetapkan prototipe Anda ke Error.prototype dan instanceof dan karya Anda menegaskan.
Namun, saya hanya akan membuang objek Anda sendiri dan hanya memeriksa properti namanya.
Edit berdasarkan komentar
Setelah melihat komentar dan mencoba mengingat mengapa saya akan menetapkan prototipe,
Error.prototype
bukannew Error()
seperti yang dilakukan Nicholas Zakas dalam artikelnya , saya membuat jsFiddle dengan kode di bawah ini:Output konsol adalah ini.
Ini mengkonfirmasi "masalah" yang saya temui adalah properti stack kesalahan adalah nomor baris tempat
new Error()
dibuat, dan bukan di manathrow e
terjadi. Namun, itu mungkin lebih baik yang memiliki efek samping dariNotImplementedError.prototype.name = "NotImplementedError"
garis yang mempengaruhi objek Kesalahan.Juga, perhatikan
NotImplementedError2
, ketika saya tidak mengatur.name
secara eksplisit, itu sama dengan "Kesalahan". Namun, seperti yang disebutkan dalam komentar, karena versi itu menetapkan prototipenew Error()
, saya dapat mengaturNotImplementedError2.prototype.name = "NotImplementedError2"
dan menjadi OK.sumber
Error.prototype
langsung mungkin bentuk yang buruk. Jika nanti Anda ingin menambahkanNotImplementedError.prototype.toString
objek sekarang alias keError.prototype.toString
- lebih baik dilakukanNotImplementedError.prototype = new Error()
.subclass.prototype = new Error()
adalah bentuk yang buruk. Anda seharusnya menggunakansubclass.prototype = Object.create(superclass.prototype)
sebagai gantinya. Saya berharap ini dapat memperbaiki masalah stack-trace juga.this.stack = new Error().stack;
NotImplementedError.prototype = Error.prototype;
tidak membuatinstanceof
memperlakukanNotImplementedError
sebagai subclass dariError
, itu membuatinstanceof
memperlakukan mereka sebagai kelas yang sama persis. Jika Anda menempelkan kode di atas ke konsol Anda dan mencobanew Error() instanceof NotImplementedError
Anda akan mendapatkannyatrue
, yang jelas salah.Semua jawaban di atas sangat mengerikan - sungguh. Bahkan yang memiliki 107 up! Jawaban sebenarnya ada di sini kawan:
Mewarisi dari objek Kesalahan - di mana properti pesan?
TL; DR:
A. Alasan
message
tidak diatur adalah bahwaError
ini adalah fungsi yang mengembalikan objek kesalahan baru dan tidak memanipulasithis
dengan cara apa pun.B. Cara untuk melakukan ini dengan benar adalah dengan mengembalikan hasil berlaku dari konstruktor, serta menetapkan prototipe dengan cara javascripty rumit yang biasa:
Anda mungkin dapat melakukan beberapa tipu daya untuk menghitung semua properti yang tidak dapat dihitung dari
tmp
Kesalahan untuk mengaturnya daripada hanya mengatur secara eksplisitstack
danmessage
, tetapi tipu daya tersebut tidak didukung yaitu <9sumber
return this
di konstruktor.temp.name = this.name = 'MyError'
, Anda bisa melakukannyatemp.name = this.name = this.constructor.name
. Dengan begitu itu akan bekerja untuk subclassMyError
juga.Di ES2015, Anda dapat menggunakannya
class
untuk melakukan ini dengan bersih:Ini tidak mengubah global
Error
prototipe, memungkinkan Anda untuk menyesuaikanmessage
,name
dan atribut lainnya, dan benar menangkap stack. Ini juga cukup mudah dibaca.Tentu saja, Anda mungkin perlu menggunakan alat seperti
babel
jika kode Anda akan berjalan di browser yang lebih lama.sumber
Jika ada yang ingin tahu tentang cara membuat kesalahan khusus dan mendapatkan jejak tumpukan:
sumber
Bagian standar ini dapat menjelaskan mengapa
Error.apply
panggilan tidak menginisialisasi objek:Dalam hal ini
Error
fungsi mungkin menentukan bahwa itu tidak disebut sebagai konstruktor, sehingga mengembalikan contoh kesalahan baru daripada menginisialisasithis
objek.Pengujian dengan kode berikut tampaknya menunjukkan bahwa inilah yang sebenarnya terjadi:
Output berikut dihasilkan ketika ini dijalankan:
sumber
this
dalamError.apply(this, arguments);
? Saya mengatakan panggilan untuk Kesalahan di sini adalah membangun objek baru, yang dibuang; tidak menginisialisasi objek yang sudah dibangun yang ditugaskannie
.NotImplementedError
implementasi Anda mengembalikanreturned
variabel?sumber
Saya punya masalah serupa dengan ini. Kesalahan saya perlu
instanceof
keduanyaError
danNotImplemented
, dan juga perlu menghasilkan backtrace yang koheren di konsol.Solusi saya:
Hasil menjalankan dengan node.js:
Kesalahan melewati ketiga kriteria saya, dan meskipun
stack
properti tidak standar, didukung di sebagian besar browser yang lebih baru yang dapat diterima dalam kasus saya.sumber
Menurut Joyent, Anda tidak boleh main-main dengan properti stack (yang saya lihat di banyak jawaban yang diberikan di sini), karena itu akan berdampak negatif pada kinerja. Inilah yang mereka katakan:
Saya suka dan ingin menyebutkan ide mereka untuk membungkus kesalahan asli yang merupakan pengganti yang bagus untuk melewati stack.
Jadi, inilah cara saya membuat kesalahan khusus, mengingat yang disebutkan di atas:
versi es5:
versi es6:
Saya telah memasukkan solusi saya ke dalam modul, ini dia: https://www.npmjs.com/package/rerror
sumber
Saya suka melakukannya seperti ini:
"{code}: {message}"
error.code
sebagai memeriksa / mem-parsing kode lebih baik dalam kode daripada memeriksa pesan, yang mungkin ingin Anda pelokalkan misalnyaerror.message
sebagai alternatiferror.toString()
sumber
Saya hanya perlu mengimplementasikan sesuatu seperti ini dan menemukan bahwa tumpukan hilang dalam implementasi kesalahan saya sendiri. Apa yang harus saya lakukan adalah membuat kesalahan dummy dan mengambil tumpukan dari itu:
sumber
Saya menggunakan Pola Konstruktor untuk membuat objek kesalahan baru. Saya mendefinisikan rantai prototipe seperti
Error
contoh. Lihat referensi konstruktor MDN Error .Anda dapat memeriksa cuplikan ini di intisari ini .
PENERAPAN
PEMAKAIAN
Konstruktor CustomError dapat menerima banyak argumen untuk membangun pesan, misalnya
Dan inilah tampilan kesalahan khusus:
sumber
Konstruktor perlu seperti metode pabrik dan mengembalikan apa yang Anda inginkan. Jika Anda membutuhkan metode / properti tambahan, Anda dapat menambahkannya ke objek sebelum mengembalikannya.
Meskipun saya tidak yakin mengapa Anda harus melakukan ini. Kenapa tidak pakai saja
new Error...
? Pengecualian khusus tidak benar-benar menambahkan banyak dalam JavaScript (atau mungkin bahasa yang tidak diketik).sumber
Ini diterapkan dengan baik di Cesium DeveloperError:
Dalam bentuknya yang disederhanakan:
sumber
error instanceof Error
ujian, yang dapat membantu.Ini implementasi saya:
Contoh penggunaan # 1:
Contoh penggunaan # 2:
sumber
Dengan mengorbankan ketidakmampuan untuk digunakan
instanceof
, berikut ini mempertahankan jejak tumpukan asli dan tidak menggunakan trik non-standar.sumber
fixError
fungsi di atas. Menambahkannew
ketika memanggil itu hanya akan membuat objek yang dibuang.Alternatif lain, mungkin tidak bekerja di semua lingkungan. Pastikan itu bekerja di nodejs 0.8 Pendekatan ini menggunakan cara tidak standar dalam memodifikasi proto prop internal.
sumber
Jika Anda menggunakan Node / Chrome. Cuplikan berikut akan memberi Anda ekstensi yang memenuhi persyaratan berikut.
err instanceof Error
err instanceof CustomErrorType
[CustomErrorType]
ketika dibuat dengan pesan[CustomErrorType: message]
ketika dibuat tanpa pesanif
pernyataan dan Anda siap melakukannya .Potongan
Pemakaian
Keluaran
sumber
Berikut ini berfungsi untuk saya yang diambil dari Kesalahan dokumentasi resmi Mozilla .
sumber
Coba objek prototipe baru untuk setiap instance dari tipe kesalahan yang ditentukan pengguna. Hal ini memungkinkan
instanceof
pemeriksaan untuk berperilaku seperti biasa plus jenis dan pesan dilaporkan dengan benar di Firefox dan V8 (Chome, nodejs).Perhatikan bahwa entri tambahan akan mendahului tumpukan yang benar.
sumber
var a = new NotImplementedError('a'), b = new NotImplementedError('b');
. Sekaranga instanceof NotImplementedError == false
danb instanceof NotImplementedError == true
Ini cara tercepat untuk melakukannya:
sumber
cara yang lebih mudah. Anda bisa membuat objek Anda mewarisi dari objek Kesalahan. Contoh:
apa yang kita lakukan adalah menggunakan pemanggilan fungsi () yang memanggil konstruktor dari kelas Kesalahan sehingga pada dasarnya sama dengan menerapkan warisan kelas dalam bahasa berorientasi objek lainnya.
sumber
MDN memiliki contoh yang sangat baik :
sumber