Kata -kata sebelumnya
Penanganan kesalahan sangat penting untuk pengembangan aplikasi web. Itu tidak dapat memprediksi kemungkinan kesalahan di muka, dan strategi pemulihan tidak dapat diadopsi terlebih dahulu, yang dapat menyebabkan pengalaman pengguna yang buruk. Karena kesalahan JavaScript dapat menyebabkan halaman web tidak dapat digunakan, sebagai pengembang, Anda harus tahu kapan, mengapa, dan apa yang akan terjadi. Artikel ini akan memperkenalkan mekanisme penanganan kesalahan dalam JavaScript secara rinci
objek kesalahan
Objek kesalahan adalah objek yang berisi informasi kesalahan dan merupakan objek asli JavaScript. Ketika kesalahan terjadi selama kode penguraian atau berjalan, mesin JavaScript akan secara otomatis menghasilkan dan melempar instance dari objek kesalahan, dan kemudian seluruh program akan terganggu di mana kesalahan terjadi.
Console.log (t); // ReferenceError Uncaught: T tidak didefinisikan
ECMA-262 menentukan bahwa objek kesalahan mencakup dua properti: pesan dan nama. Atribut pesan menyimpan pesan kesalahan, sedangkan atribut nama menyimpan jenis kesalahan
// Umumnya, pernyataan coba-katch digunakan untuk menangkap kesalahan coba {t;} catch (ex) {console.log (ex.message); // t tidak didefinisikan console.log (ex.name); // referensiError}Browser juga memperluas properti objek kesalahan dan menambahkan informasi lain yang relevan. Di antara mereka, yang paling banyak diterapkan oleh produsen browser adalah atribut tumpukan, yang menunjukkan informasi jejak tumpukan (Safari tidak mendukungnya)
coba {t;} catch (ex) {console.log (ex.stack); //@file: /// d: /wamp/www/form.html: 12: 2}Tentu saja, Anda dapat menggunakan konstruktor kesalahan () untuk membuat objek kesalahan. Jika parameter pesan ditentukan, objek kesalahan akan menggunakannya sebagai properti pesannya; Jika tidak ditentukan, itu akan menggunakan string default yang telah ditentukan sebagai nilai properti
kesalahan baru (); kesalahan baru (pesan); // Umumnya, gunakan pernyataan lemparan untuk melempar kesalahan lemparan kesalahan baru ('tes'); // kesalahan tanpa batas: testthrow new error (); // kesalahan tanpa batas function userError (pesan) {this.message = pesan; this.name = "usereRror";} usereRror.prototype = new error (); usereRror.prototype.constructor = userError; lempar pengguna baru ("errorMessage"); // Usererror Uncaught: errormessage ("errorMessage"); // Usererror Uncaught: ErrorMessageKetika konstruktor kesalahan () dipanggil secara langsung seperti fungsi tanpa menggunakan operator baru, perilakunya sama seperti ketika operator baru dipanggil
Error (); error (pesan); Throw error ('test'); // kesalahan tanpa batas: testthrow error (); // kesalahan tanpa batasObjek kesalahan memiliki metode tostring (), yang mengembalikan atribut pesan dari objek kesalahan.
var test = kesalahan baru ('teserRor'); console.log (test.toString ()); // 'error: testerror'tipe kesalahan
Ada banyak jenis kesalahan yang mungkin terjadi selama eksekusi kode. Setiap kesalahan memiliki jenis kesalahan yang sesuai, dan ketika kesalahan terjadi, objek kesalahan dari jenis yang sesuai akan dilemparkan. ECMA-262 mendefinisikan 7 jenis kesalahan berikut:
ErrorEvalError (Evalerror) RangeError (RangeError) ReferencerError (ReferenceError) SyntaxError (SyntaxError) TypeError (TypeError) Urierror (Urierror)
Di mana, kesalahan adalah tipe dasar, dan tipe kesalahan lainnya diwarisi dari jenis ini. Oleh karena itu, semua jenis kesalahan berbagi satu set properti yang sama. Kesalahan tipe kesalahan jarang terjadi, dan jika ada, mereka juga dilemparkan oleh browser; Tujuan utama dari jenis dasar ini adalah agar pengembang melempar kesalahan khusus
【Evalerror (eval error)】
Ketika fungsi eval tidak dieksekusi dengan benar, kesalahan evaluasi akan dilemparkan. Jenis kesalahan ini tidak lagi muncul di ES5, tetapi akan terus dipertahankan untuk memastikan kompatibilitas dengan kode sebelumnya.
【RangeError (RangeError)】
Kesalahan jenis rangeError akan dipicu ketika nilai melebihi kisaran yang sesuai, terutama termasuk melebihi kisaran panjang array dan melebihi rentang nilai angka.
Array baru (-1); // RangeRror yang tidak tertulis: array array tidak valid array (number.max_value); // rangeRror yang tidak tertulis: Panjang array yang tidak valid (1234) .to exponential (21); // RangeRror Uncaught: Toexponential () argumen harus antara 0 dan 20 (1234). argumen toexponential () harus antara 0 dan 20
【ReferenceError (Kesalahan referensi)】
ReferenceError akan dipicu saat mengacu pada kesalahan variabel atau tipe lvalue yang tidak ada.
A; // ReferenceError yang Tak Terbaik: A tidak ditentukan1 ++; // Referenceerror Uncaught: Ekspresi sisi kiri tidak valid dalam operasi postfix
【Sintakserror (SyntaxError)】
Ketika aturan sintaks tidak terpenuhi, sintakser akan dilemparkan (kesalahan sintaksis)
// Kesalahan Nama Variabel Var 1A; // Sintakser Tanpa Diputus: Nomor Tidak Terduga // Konsol Bracket yang Hilang 'Hello'); // Sintakser Tanpa Ditemukan: String Tak Terduga
【TypeError (jenis kesalahan)】
TipeError Tipe Error akan disebabkan ketika tipe tak terduga disimpan dalam variabel, atau saat mengakses metode yang tidak ada. Meskipun penyebab kesalahan beragam, pada akhirnya, itu karena jenis variabel tidak memenuhi persyaratan saat melakukan jenis operasi tertentu.
var o = baru 10; // TypeError Uncaught: 10 bukan konstruktoral ('name' in true); // TypeError Uncaught: tidak dapat menggunakan 'dalam' operator untuk mencari 'nama' di truefunction.prototype.toString.call ('name'); // TipeError Uncauphing: function.prototype.tostring tidak generasi Generot【Urierror (error uri)】
Urierror adalah kesalahan yang dilemparkan ketika parameter fungsi terkait URI salah. Ini terutama melibatkan enam fungsi: encodeuri (), decodeuri (), encodeuricomponent (), decodeuricomponent (), Escape () dan Unescape ().
decodeuri ('%2'); // Urierror: Uri Malformedperistiwa kesalahan
Kesalahan apa pun yang tidak diproses melalui TRY-Catch akan memicu peristiwa kesalahan objek jendela
Acara kesalahan dapat menerima tiga parameter: pesan kesalahan, URL di mana kesalahan berada, dan nomor baris. Dalam kebanyakan kasus, hanya pesan kesalahan yang berguna karena URL hanya memberikan lokasi dokumen, dan nomor baris mengacu pada baris kode yang dapat dari kode javascript tertanam atau dari file eksternal.
Untuk menentukan event handler kesalahan, Anda dapat menggunakan teknologi level DOM0 atau menggunakan format standar acara tingkat DOM2
// dom0 level window.onError = function (pesan, url, baris) {waspada (pesan);} // dom2 level window.addeventListener ("error", function (pesan, url, baris) {peringatan (pesan);});Apakah browser menampilkan pesan kesalahan standar tergantung pada nilai pengembalian OnError. Jika nilai pengembalian salah, pesan kesalahan ditampilkan di konsol; Jika nilai pengembalian benar, itu tidak ditampilkan
// Konsol menampilkan window pesan kesalahan.onError = function (pesan, url, baris) {peringatan (pesan); return false;} a; // konsol tidak menampilkan window.onError = function (pesan, url, baris) {waspada (pesan); return true;} a;Acara ini adalah lini pertahanan terakhir untuk menghindari kesalahan pelaporan browser. Idealnya, Anda tidak boleh menggunakannya bila memungkinkan. Selama Anda dapat menggunakan pernyataan mencoba-tangkapan dengan tepat, tidak akan ada kesalahan yang diserahkan ke browser dan peristiwa kesalahan tidak akan dipicu.
Gambar juga mendukung peristiwa kesalahan. Selama URL dalam karakteristik SRC dari gambar tidak dapat mengembalikan format gambar yang diakui, peristiwa kesalahan akan dipicu. Pada saat ini, acara kesalahan mengikuti format DOM dan mengembalikan objek acara yang menargetkan gambar sebagai target
Kotak peringatan muncul saat gambar dimuat. Ketika peristiwa kesalahan terjadi, proses pengunduhan gambar telah berakhir, yang berarti tidak dapat diunduh lagi.
var image = gambar baru (); image.src = 'smilex.gif'; image.onError = function (e) {console.log (e);}Lempar pernyataan dan lempar kesalahan
Pernyataan lemparan digunakan untuk melempar kesalahan. Ketika kesalahan dilemparkan, Anda harus menentukan nilai pada pernyataan Throw. Jenis apa nilai ini? Tidak ada persyaratan.
[Catatan] Proses melempar kesalahan diblokir, dan kode selanjutnya tidak akan dijalankan
Throw 12345; Throw 'Hello World'; Throw True; Throw {Name: 'JavaScript'};Anda dapat menggunakan pernyataan lemparan untuk secara manual melempar objek kesalahan
Lempar kesalahan baru ('sesuatu yang buruk terjadi'); lempar sintakser baru ('Saya tidak menyukai sintaksis Anda.'); Lemparkan TypeError baru ('Jenis variabel apa yang Anda ambil untuk saya?'); Lempar rangeerror baru ('Maaf, Anda tidak ada yang baru saja. ReferenceError ('Anda tidak mengutip referensi Anda dengan benar');Menggunakan rantai prototipe juga dapat membuat tipe kesalahan khusus dengan mengarahkan kesalahan (rantai prototipe diperkenalkan pada Bab 6). Pada titik ini, Anda perlu menentukan nama dan atribut pesan untuk jenis kesalahan yang baru dibuat
Browser memperlakukan tipe kesalahan khusus yang diwarisi dari kesalahan seperti jenis kesalahan lainnya. Membuat kesalahan khusus bermanfaat jika Anda ingin menangkap kesalahan yang Anda lempar dan perlakukan secara berbeda dari kesalahan browser.
function customError (pesan) {this.name = 'customError'; this.message = pesan;} customError.prototype = new error (); Lempar CustomError baru ('Pesan Saya');Ketika pernyataan lemparan ditemui, kode akan berhenti dieksekusi segera. Kode akan terus mengeksekusi hanya jika pernyataan mencoba-tangkapan menangkap nilai yang dilemparkan.
Penjelasan yang lebih rinci adalah: Ketika pengecualian dilemparkan, penerjemah JavaScript akan segera menghentikan logika yang saat ini dieksekusi dan melompat ke penangan pengecualian terdekat. Penangan pengecualian ditulis dalam klausa tangkapan dari pernyataan mencoba-tangkapan. Jika blok kode yang melempar pengecualian tidak memiliki klausa tangkapan terkait, penerjemah akan memeriksa blok kode tertutup tingkat lebih tinggi untuk melihat apakah ia memiliki penangan pengecualian terkait. Dan seterusnya sampai penangan pengecualian ditemukan. Jika fungsi yang melempar pengecualian tidak menangani pernyataan mencoba-tangkapannya, pengecualian akan disebarkan ke atas ke kode yang memanggil fungsi. Dengan cara ini, pengecualian akan diperbanyak ke atas sepanjang struktur leksikal dari metode JavaScript dan tumpukan panggilan. Jika tidak ada pengecualian penangan yang ditemukan, JavaScript akan menangani pengecualian sebagai kesalahan program dan melaporkannya kepada pengguna
Coba tangkap pernyataan dan tangkap kesalahan
ECMA-262 Edition 3 memperkenalkan pernyataan mencoba-tangkapan sebagai cara standar untuk menangani pengecualian dalam JavaScript, digunakan untuk menangkap dan menangani kesalahan
Di antara mereka, klausa coba menentukan blok kode di mana pengecualian yang perlu diproses berada. Klausa tangkapan mengikuti klausa percobaan. Ketika pengecualian terjadi di suatu tempat di blok coba, logika kode di dalam tangkapan dipanggil. Klausa tangkapan diikuti oleh blok akhirnya, di mana kode pembersih ditempatkan. Terlepas dari apakah pengecualian terjadi di blok coba, logika di dalam blok akhirnya akan selalu dieksekusi. Meskipun tangkapan dan akhirnya opsional, klausa coba membutuhkan setidaknya satu dari keduanya untuk membentuk pernyataan lengkap dengannya.
Semua blok pernyataan coba/tangkap/akhirnya perlu dilampirkan dengan kawat gigi keriting. Kawat gigi di sini diperlukan. Bahkan jika hanya ada satu pernyataan dalam klausa, kawat gigi keriting tidak dapat dihilangkan.
Cobalah {// Secara umum, kode di sini tidak akan menyebabkan masalah // tetapi kadang -kadang pengecualian akan dilemparkan langsung oleh pernyataan lemparan atau secara tidak langsung dilemparkan dengan memanggil metode} tangkapan (e) {// jika dan hanya jika pengecualian ini dilemparkan oleh beberapa alasan, Kode di sini akan dijalankan // di sini Anda dapat memperoleh referensi ke objek kesalahan atau nilai -nilai lain yang diterapkan oleh Nilai -Nilai -Nilai -Nilai lain, Kode ini akan dijalankan // di sini Anda dapat memperoleh referensi ke objek kesalahan atau nilai -nilai lain dari Nilai -Nilai -Nilai -Nilai -Nilai lain, Kode ini akan dijalankan / Pengecualian, dan Anda juga dapat melontarkan kembali pengecualian dengan pernyataan lemparan} akhirnya {// terlepas dari apakah pernyataan coba melempar pengecualian, logika di akhirnya akan selalu dieksekusi, dan cara untuk menghentikan blok pernyataan coba adalah: // 1. Berakhir secara normal. Setelah menjalankan pernyataan terakhir dari blok pernyataan // 2. Hentikan melalui istirahat, lanjutkan atau kembali pernyataan // 3. Lempar pengecualian, pengecualian ditangkap oleh klausa tangkapan // 4. Lempar pengecualian, pengecualian tidak tertangkap, terus menyebar ke atas}Secara umum, masukkan semua kode yang mungkin melempar kesalahan di blok pernyataan coba, dan masukkan kode yang digunakan untuk penanganan kesalahan di blok tangkapan
Jika ada kode dalam kesalahan Coba Blok, proses eksekusi kode akan segera keluar dan blok tangkapan akan dieksekusi. Pada saat ini, blok tangkapan akan menerima objek dengan pesan kesalahan. Informasi aktual yang terkandung dalam objek ini akan bervariasi dari browser ke browser, tetapi yang umum adalah bahwa ada atribut pesan yang menyimpan pesan kesalahan
[Catatan] Pastikan untuk memberi nama objek kesalahan. Jika mengosongkannya, kesalahan sintaks akan dilaporkan.
Coba {q;} catch (error) {waspada (error.message); // q tidak didefinisikan} // sintakserror yang tidak dibawa: token tak terduga) coba {q;} catch () {waspada (error.message);}Catch menerima parameter yang menunjukkan nilai yang dilemparkan oleh blok Coba Kode
function throwit (pengecualian) {coba {lempar pengecualian; } catch (e) {console.log ('tertangkap:'+ e); }} throwit (3); // tertangkap: 3throwit ('hello'); // tertangkap: hellothrowit (kesalahan baru ('kesalahan terjadi')); // tertangkap: kesalahan: kesalahan terjadi terjadiSetelah blok kode tangkapan menangkap kesalahan, program tidak akan terganggu dan akan terus mengeksekusi sesuai dengan proses normal.
coba {throw "error";} catch (e) {console.log (111);} console.log (222); // 111 // 222Untuk menangkap berbagai jenis kesalahan, pernyataan penilaian dapat ditambahkan ke blok kode tangkapan
coba {foo.bar ();} catch (e) {if (e instanceof evaleRror) {console.log (e.name + ":" + e.message); } else if (e instanceof rangeerror) {console.log (e.name + ":" + e.message); } // ...}Meskipun klausa akhirnya opsional dalam pernyataan TRY-CATCE, setelah klausa akhirnya digunakan, kodenya akan dieksekusi apa pun yang terjadi. Dengan kata lain, semua kode dalam blok pernyataan coba dieksekusi secara normal, dan akhirnya klausa akan dieksekusi; Jika blok pernyataan tangkapan dieksekusi karena kesalahan, klausa akhirnya masih akan dieksekusi. Selama kode tersebut berisi klausa akhirnya, tidak peduli kode apa yang terkandung dalam blok Coba atau Catch Pernyataan - atau bahkan pernyataan pengembalian, eksekusi klausul akhirnya tidak akan dicegah.
// Kesalahan tidak tertangkap karena tidak ada blok pernyataan tangkapan. Setelah mengeksekusi blok kode akhirnya, program mengganggu fungsi pembersihan () di mana kesalahan dilemparkan. function cleanSup () {coba {lempar kesalahan baru ('error ...'); Console.log ('Baris ini tidak akan dieksekusi'); } akhirnya {console.log ('Lengkapi pekerjaan pembersihan'); }} cleanSup (); // lengkapi pekerjaan pembersihan // kesalahan: kesalahan ... function testFinNally () {coba {return 2; } catch (error) {return 1; } akhirnya {return 0; }} testfinnally (); // 0[Catatan] Nilai jumlah pernyataan pengembalian diperoleh sebelum blok kode akhirnya dijalankan.
var count = 0; function countup () {coba {return count; } akhirnya {count ++; }} countUp (); // 0console.log (count); // 1 fungsi f () {coba {console.log (0); lempar "bug"; } catch (e) {console.log (1); Kembali Benar; // Kalimat ini akan ditunda sampai akhir blok kode akhirnya sebelum menjalankan konsol.log (2); // itu tidak akan berjalan} akhirnya {console.log (3); mengembalikan false; // Kalimat ini akan menimpa konsol pengembalian kalimat sebelumnya (4); // itu tidak akan menjalankan} console.log (5); // Ini tidak akan menjalankan} var result = f (); // 0 // 1 // 3console.log (hasil); // false【Tips】 lingkup level blok
Penggunaan umum pernyataan mencoba-tangkapan adalah untuk membuat lingkup level blok di mana variabel yang dinyatakan hanya valid di dalam tangkapan
ES6 memperkenalkan kata kunci LET untuk membuat ruang lingkup level blok untuk variabel yang dinyatakannya. Namun, dalam situasi saat ini ES3 dan ES5, pernyataan mencoba-tangkapan sering digunakan untuk mencapai efek yang sama
Dari kode berikut, E hanya ada di dalam klausa tangkapan, dan kesalahan akan dilemparkan ketika mencoba merujuknya dari tempat lain.
coba {lempar kesalahan baru (); // throttling kesalahan} catch (e) {console.log (e); // error (...)} console.log (e); // ReferencerRor Uncaught: E tidak ditentukanInti dari penanganan kesalahan umum adalah terlebih dahulu mengetahui kesalahan apa yang akan terjadi dalam kode. Karena JavaScript secara longgar diketik dan tidak memverifikasi parameter fungsi, kesalahan hanya akan terjadi selama kode. Secara umum, tiga jenis kesalahan perlu diperhatikan: Ketik kesalahan konversi, kesalahan tipe data, dan kesalahan komunikasi
【Ketik kesalahan konversi】
Ketik kesalahan konversi terjadi saat menggunakan operator, atau menggunakan struktur bahasa lain dari tipe data yang dapat secara otomatis mengonversi nilai.
Pernyataan kontrol aliran rentan untuk mengetik kesalahan konversi. Pernyataan seperti IF akan secara otomatis mengonversi nilai apa pun menjadi boolean sebelum menentukan operasi berikutnya. Terutama jika pernyataan, jika digunakan secara tidak benar, mereka kemungkinan besar akan membuat kesalahan.
Variabel yang tidak digunakan secara otomatis ditetapkan nilai yang tidak ditentukan. Nilai yang tidak ditentukan dapat dikonversi ke nilai boolean false, sehingga pernyataan IF dalam fungsi berikut sebenarnya hanya berlaku untuk kasus di mana parameter ketiga disediakan. Masalahnya adalah tidak hanya tidak terdefinisi untuk dikonversi menjadi false, juga bukan hanya nilai string yang dapat dikonversi menjadi benar. Misalnya, jika parameter ketiga adalah nilai 0, tes pernyataan IF akan gagal, dan tes nilai logaritmik 1 akan lulus
fungsi concat (str1, str2, str3) {var result = str1 + str2; if (str3) {// benar -benar tidak menghasilkan += str3; } return hasil;}Menggunakan nilai non-Boolean dalam pernyataan kontrol aliran adalah sumber kesalahan yang sangat umum. Untuk menghindari kesalahan seperti itu, perlu untuk melewati nilai boolean ketika kondisinya dibandingkan. Faktanya, melakukan beberapa bentuk perbandingan dapat mencapai ini
fungsi concat (str1, str2, str3) {var result = str1 + str2; if (typeOf str3 == 'string') {// Hasil yang lebih cocok += str3; } return hasil;}【Kesalahan tipe data】
JavaScript secara longgar diketik dan tidak akan dibandingkan untuk memastikan bahwa tipe data mereka benar sampai variabel dan parameter fungsi digunakan. Untuk memastikan bahwa kesalahan tipe data tidak akan terjadi, hanya kode deteksi tipe data yang sesuai yang dapat ditulis. Kesalahan tipe data kemungkinan besar terjadi ketika memberikan nilai yang tidak terduga ke fungsi plot
// fungsi yang tidak aman, nilai non-array apa pun akan menyebabkan fungsi kesalahan reversesor (values) {if (values) {values.sort (); nilai.reverse (); }}Kesalahan umum lainnya adalah membandingkan parameter dengan nilai nol. Dibandingkan dengan null hanya memastikan bahwa nilai yang sesuai tidak nol dan tidak terdefinisi. Untuk memastikan bahwa nilai yang dilewati valid, itu tidak cukup untuk mendeteksi nilai nol saja
// fungsi tidak aman, nilai non-array apa pun akan menyebabkan fungsi kesalahan reversesor (values) {if (values! = Null) {values.sort (); nilai.reverse (); }}Jika suatu objek yang berisi metode sort () (bukan array) dilewati, itu akan melewati deteksi, tetapi kesalahan dapat terjadi saat memanggil fungsi terbalik ()
// fungsi tidak aman, nilai non-array apa pun akan menyebabkan fungsi kesalahan reversesort (nilai) {if (typeof values.sort == 'function') {values.sort (); nilai.reverse (); }}Jika Anda tahu persis jenis apa yang harus Anda lewati, yang terbaik adalah menggunakan instance dari untuk mendeteksi tipe datanya
// Nilai yang aman, non-array diabaikan fungsi reversesort (nilai) {if (nilai instance dari array) {values.sort (); nilai.reverse (); }}【Kesalahan komunikasi】
Dengan munculnya pemrograman AJAX, telah menjadi hal biasa bagi aplikasi web untuk memuat informasi atau fungsionalitas secara dinamis selama siklus hidup mereka. Namun, komunikasi apa pun antara JavaScript dan server dapat menyebabkan kesalahan
Masalah yang paling umum adalah bahwa data tidak dikodekan menggunakan encodeuricomponent () sebelum mengirimnya ke server
// kesalahan http://www.yourdomain.com/?redir=http://www.sometherdomain.com?a=b&c=d//call encodeuricomponent () untuk semua string setelah 'redir =' dapat menyelesaikan masalah ini http://www.yourdomain.com/?redir=http:%3a%2f%2fwww.sometherdomain.com%3fa%3db%26c%3dd
Artikel di atas secara komprehensif memahami mekanisme penanganan kesalahan dalam JavaScript. Ini semua konten yang saya bagikan dengan Anda. Saya harap Anda dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.