คำก่อนหน้านี้
การจัดการข้อผิดพลาดเป็นสิ่งสำคัญสำหรับการพัฒนาเว็บแอปพลิเคชัน ไม่สามารถทำนายข้อผิดพลาดที่เป็นไปได้ล่วงหน้าและกลยุทธ์การกู้คืนไม่สามารถนำมาใช้ล่วงหน้าซึ่งอาจนำไปสู่ประสบการณ์ผู้ใช้ที่ไม่ดี เนื่องจากข้อผิดพลาด JavaScript ใด ๆ สามารถทำให้หน้าเว็บไม่สามารถใช้งานได้ในฐานะนักพัฒนาคุณต้องรู้ว่าทำไมทำไมและจะเกิดอะไรขึ้น บทความนี้จะแนะนำกลไกการจัดการข้อผิดพลาดใน JavaScript ในรายละเอียด
วัตถุข้อผิดพลาด
วัตถุข้อผิดพลาดเป็นวัตถุที่มีข้อมูลข้อผิดพลาดและเป็นวัตถุดั้งเดิมของ JavaScript เมื่อเกิดข้อผิดพลาดระหว่างการแยกวิเคราะห์รหัสหรือการรันเอ็นจิ้น JavaScript จะสร้างและโยนอินสแตนซ์ของวัตถุข้อผิดพลาดโดยอัตโนมัติจากนั้นโปรแกรมทั้งหมดจะถูกขัดจังหวะเมื่อเกิดข้อผิดพลาด
console.log (t); // uncaught ReferenceRoror: t ไม่ได้กำหนดไว้
ECMA-262 ระบุว่าวัตถุข้อผิดพลาดมีคุณสมบัติสองประการ: ข้อความและชื่อ แอตทริบิวต์ข้อความบันทึกข้อความแสดงข้อผิดพลาดในขณะที่แอตทริบิวต์ชื่อจะบันทึกประเภทข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
// โดยทั่วไปใช้คำสั่งลองจับเพื่อจับข้อผิดพลาด
พยายาม{
t;
} catch (ex) {
console.log (ex.message); // t ไม่ได้กำหนดไว้
console.log (ex.name); // referenterror
-
เบราว์เซอร์ยังขยายคุณสมบัติของวัตถุข้อผิดพลาดและเพิ่มข้อมูลอื่น ๆ ที่เกี่ยวข้อง ในหมู่พวกเขาผู้ผลิตเบราว์เซอร์ที่ดำเนินการมากที่สุดคือแอตทริบิวต์สแต็กซึ่งบ่งบอกถึงข้อมูลการติดตามสแต็ก (Safari ไม่รองรับ)
การคัดลอกรหัสมีดังนี้:
พยายาม{
t;
} catch (ex) {
console.log (ex.stack); //@file: /// d: /wamp/www/form.html: 12: 2
-
แน่นอนคุณสามารถใช้ข้อผิดพลาด () ตัวสร้างเพื่อสร้างวัตถุข้อผิดพลาด หากระบุพารามิเตอร์ข้อความวัตถุข้อผิดพลาดจะใช้เป็นคุณสมบัติข้อความ หากไม่ได้ระบุจะใช้สตริงเริ่มต้นที่กำหนดไว้ล่วงหน้าเป็นค่าของคุณสมบัติ
การคัดลอกรหัสมีดังนี้:
ข้อผิดพลาดใหม่ ();
ข้อผิดพลาดใหม่ (ข้อความ);
// โดยทั่วไปใช้คำสั่งโยนเพื่อโยนข้อผิดพลาด
โยนข้อผิดพลาดใหม่ ('ทดสอบ'); // ข้อผิดพลาดที่ไม่ถูกต้อง: ทดสอบ
โยนข้อผิดพลาดใหม่ (); // ข้อผิดพลาดที่ไม่ถูกต้อง
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น userError (ข้อความ) {
this.message = ข้อความ;
this.name = "UserError";
-
userError.prototype = ข้อผิดพลาดใหม่ ();
userError.prototype.constructor = userError;
โยน userError ใหม่ ("errorMessage"); // userError ที่ไม่ได้รับการตรวจสอบ: errorMessage
เมื่อตัวสร้างข้อผิดพลาด () เรียกว่าโดยตรงเหมือนฟังก์ชั่นโดยไม่ต้องใช้ตัวดำเนินการใหม่พฤติกรรมของมันจะเหมือนกับเมื่อมีการเรียกผู้ประกอบการใหม่
การคัดลอกรหัสมีดังนี้:
ข้อผิดพลาด();
ข้อผิดพลาด (ข้อความ);
การโยนข้อผิดพลาด ('ทดสอบ'); // ข้อผิดพลาดที่ไม่ถูกต้อง: ทดสอบ
โยนข้อผิดพลาด (); // ข้อผิดพลาดที่ไม่ได้รับการร้องขอ
วัตถุข้อผิดพลาดมีเมธอด toString () ซึ่งส่งคืนแอตทริบิวต์ข้อความของวัตถุข้อผิดพลาด
การคัดลอกรหัสมีดังนี้:
VAR TEST = ข้อผิดพลาดใหม่ ('TestError');
console.log (test.toString ()); // 'ข้อผิดพลาด: TestError'
ประเภทข้อผิดพลาด
มีข้อผิดพลาดหลายประเภทที่อาจเกิดขึ้นระหว่างการดำเนินการรหัส ข้อผิดพลาดแต่ละข้อมีประเภทข้อผิดพลาดที่สอดคล้องกันและเมื่อเกิดข้อผิดพลาดวัตถุข้อผิดพลาดของประเภทที่เกี่ยวข้องจะถูกโยนทิ้ง ECMA-262 กำหนด 7 ประเภทข้อผิดพลาดต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
ข้อผิดพลาด
Everferor (ข้อผิดพลาดในการประเมิน)
Rangeerror (Rangeerror)
ReferenceRoror (ข้อผิดพลาดอ้างอิง)
SyntaxError (ข้อผิดพลาดทางไวยากรณ์)
TypeError (ประเภทข้อผิดพลาด)
UrierRor (ข้อผิดพลาด URI)
โดยที่ข้อผิดพลาดคือประเภทพื้นฐานและประเภทข้อผิดพลาดอื่น ๆ ได้รับการสืบทอดมาจากประเภทนี้ ดังนั้นประเภทข้อผิดพลาดทั้งหมดจึงแบ่งปันชุดคุณสมบัติเดียวกัน ข้อผิดพลาดประเภทข้อผิดพลาดนั้นหายากและหากมีพวกเขาก็จะถูกโยนโดยเบราว์เซอร์; วัตถุประสงค์หลักของประเภทฐานนี้คือสำหรับนักพัฒนาในการโยนข้อผิดพลาดที่กำหนดเอง
【 EvalError (ข้อผิดพลาดการประเมิน) 】
เมื่อฟังก์ชั่นการประเมินไม่ถูกดำเนินการอย่างถูกต้องข้อผิดพลาดของผู้ประเมินจะถูกโยนลงไป ประเภทข้อผิดพลาดนี้ไม่ปรากฏใน ES5 อีกต่อไป แต่จะยังคงได้รับการเก็บรักษาไว้เพื่อให้แน่ใจว่าเข้ากันได้กับรหัสก่อนหน้า
【 rangeerror (rangeerror) 】
ข้อผิดพลาดของประเภท rangeerror จะถูกทริกเกอร์เมื่อค่าเกินช่วงที่สอดคล้องกันส่วนใหญ่รวมถึงเกินช่วงความยาวอาร์เรย์และเกินช่วงค่าตัวเลข
การคัดลอกรหัสมีดังนี้:
อาร์เรย์ใหม่ (-1); // uncaught rangeerror: ความยาวอาร์เรย์ที่ไม่ถูกต้อง
อาร์เรย์ใหม่ (number.max_value); // uncaught rangeerror: ความยาวอาร์เรย์ที่ไม่ถูกต้อง
(1234) .toexponential (21); // uncaught rangeerror: toexponential () การโต้แย้งต้องอยู่ระหว่าง 0 ถึง 20
(1234) .toexponential (-1); //// uncaught rangeerror: toExponential () การโต้แย้งต้องอยู่ระหว่าง 0 ถึง 20
【 ReferenceRoror (ข้อผิดพลาดอ้างอิง) 】
ReferenceRoror จะถูกทริกเกอร์เมื่ออ้างถึงข้อผิดพลาดที่ไม่มีการยืนยันหรือข้อผิดพลาดประเภท lvalue
A; // uncaught ReferenceRorror: A ไม่ได้กำหนดไว้
1 ++; // uncerference referenterror: นิพจน์ด้านซ้ายมือไม่ถูกต้องในการดำเนินการ postfix
【 SyntaxError (SyntaxError) 】
เมื่อไม่ตรงตามกฎไวยากรณ์จะมีการโยนไวยากรณ์ (ข้อผิดพลาดไวยากรณ์)
การคัดลอกรหัสมีดังนี้:
// ชื่อตัวแปรไม่ถูกต้อง
var 1a; // uncaught syntaxerror: หมายเลขที่ไม่คาดคิด
// วงเล็บหายไป
console.log 'hello'); // uncaught syntaxerror: สตริงที่ไม่คาดคิด
【 typeError (ประเภทข้อผิดพลาด) 】
ข้อผิดพลาดประเภทประเภทของประเภทจะเกิดขึ้นเมื่อประเภทที่ไม่คาดคิดถูกเก็บไว้ในตัวแปรหรือเมื่อเข้าถึงวิธีที่ไม่มีอยู่จริง แม้ว่าสาเหตุของข้อผิดพลาดมีความหลากหลายในที่สุดก็เป็นเพราะประเภทของตัวแปรไม่ตรงตามข้อกำหนดเมื่อทำการดำเนินการเฉพาะประเภท
การคัดลอกรหัสมีดังนี้:
var o = new 10; // uncaught typeerror: 10 ไม่ใช่ตัวสร้าง
การแจ้งเตือน ('ชื่อ' เป็นจริง); // uncaught typeError: ไม่สามารถใช้ 'ใน' ตัวดำเนินการเพื่อค้นหา 'ชื่อ' เป็นจริง
function.prototype.toString.call ('ชื่อ'); // uncaught typeError: function.prototype.toString ไม่ใช่ทั่วไป
【 urierror (ข้อผิดพลาด URI) 】
Urierror เป็นข้อผิดพลาดที่เกิดขึ้นเมื่อพารามิเตอร์ของฟังก์ชั่นที่เกี่ยวข้องกับ URI ไม่ถูกต้อง ส่วนใหญ่เกี่ยวข้องกับหกฟังก์ชั่น: encodeuri (), decodeuri (), encodeuricomponent (), decodeuricomponent (), escape () และ unescape ()
decodeuri ('%2'); // urierror: uri malformed
เหตุการณ์ข้อผิดพลาด
ข้อผิดพลาดใด ๆ ที่ไม่ได้ประมวลผลผ่านการลองจับจะทำให้เกิดเหตุการณ์ข้อผิดพลาดของวัตถุหน้าต่าง
เหตุการณ์ข้อผิดพลาดสามารถรับสามพารามิเตอร์: ข้อความแสดงข้อผิดพลาด, URL ที่เกิดข้อผิดพลาดและหมายเลขบรรทัด ในกรณีส่วนใหญ่ข้อความแสดงข้อผิดพลาดมีประโยชน์เท่านั้นเนื่องจาก URL ให้ตำแหน่งของเอกสารเท่านั้นและหมายเลขบรรทัดหมายถึงบรรทัดของรหัสที่สามารถมาจากรหัส JavaScript แบบฝังตัวหรือจากไฟล์ภายนอก
ในการระบุตัวจัดการเหตุการณ์ข้อผิดพลาดคุณสามารถใช้เทคโนโลยีระดับ DOM0 หรือใช้รูปแบบมาตรฐานของกิจกรรมระดับ DOM2
การคัดลอกรหัสมีดังนี้:
// dom0 ระดับ
window.onerror = function (ข้อความ, url, line) {
การแจ้งเตือน (ข้อความ);
-
// ระดับ DOM2
window.addeventListener ("ข้อผิดพลาด", ฟังก์ชัน (ข้อความ, url, line) {
การแจ้งเตือน (ข้อความ);
-
ไม่ว่าเบราว์เซอร์จะแสดงข้อความแสดงข้อผิดพลาดมาตรฐานขึ้นอยู่กับค่าส่งคืนของ ONERROR หรือไม่ หากค่าที่ส่งคืนเป็นเท็จข้อความแสดงข้อผิดพลาดจะปรากฏในคอนโซล หากค่าส่งคืนเป็นจริงจะไม่แสดง
การคัดลอกรหัสมีดังนี้:
// คอนโซลแสดงข้อความแสดงข้อผิดพลาด
window.onerror = function (ข้อความ, url, line) {
การแจ้งเตือน (ข้อความ);
กลับเท็จ;
-
a;
// คอนโซลไม่แสดงข้อความแสดงข้อผิดพลาด
window.onerror = function (ข้อความ, url, line) {
การแจ้งเตือน (ข้อความ);
กลับมาจริง;
-
a;
ตัวจัดการเหตุการณ์นี้เป็นบรรทัดสุดท้ายของการป้องกันเพื่อหลีกเลี่ยงข้อผิดพลาดในการรายงานเบราว์เซอร์ ตามหลักการแล้วคุณไม่ควรใช้เมื่อเป็นไปได้ ตราบใดที่คุณสามารถใช้คำสั่งลองจับได้อย่างเหมาะสมจะไม่มีข้อผิดพลาดที่ส่งไปยังเบราว์เซอร์และเหตุการณ์ข้อผิดพลาดจะไม่ถูกเรียกใช้
ภาพยังรองรับเหตุการณ์ข้อผิดพลาด ตราบใดที่ URL ในลักษณะ SRC ของภาพไม่สามารถส่งคืนรูปแบบภาพที่รู้จักได้เหตุการณ์ข้อผิดพลาดจะถูกทริกเกอร์ ในเวลานี้เหตุการณ์ข้อผิดพลาดจะติดตามรูปแบบ DOM และส่งคืนวัตถุเหตุการณ์ที่กำหนดเป้าหมายภาพเป็นเป้าหมาย
กล่องคำเตือนจะปรากฏขึ้นเมื่อมีการโหลดภาพ เมื่อเหตุการณ์ข้อผิดพลาดเกิดขึ้นกระบวนการดาวน์โหลดรูปภาพได้สิ้นสุดลงซึ่งหมายความว่าไม่สามารถดาวน์โหลดได้อีกครั้ง
การคัดลอกรหัสมีดังนี้:
ภาพ var = ภาพใหม่ ();
image.src = 'smilex.gif';
image.onerror = function (e) {
console.log (e);
-
โยนคำสั่งและโยนข้อผิดพลาด
คำสั่งการโยนใช้เพื่อโยนข้อผิดพลาด เมื่อเกิดข้อผิดพลาดคุณต้องระบุค่าไปยังคำสั่งการโยน ค่านี้เป็นประเภทใด? ไม่มีข้อกำหนด
[หมายเหตุ] กระบวนการโยนข้อผิดพลาดถูกบล็อกและรหัสที่ตามมาจะไม่ถูกเรียกใช้งาน
การคัดลอกรหัสมีดังนี้:
โยน 12345;
โยน 'Hello World';
โยนจริง;
โยน {ชื่อ: 'JavaScript'};
คุณสามารถใช้คำสั่งโยนเพื่อโยนวัตถุข้อผิดพลาดด้วยตนเอง
การคัดลอกรหัสมีดังนี้:
โยนข้อผิดพลาดใหม่ ('สิ่งที่ไม่ดีเกิดขึ้น');
โยน syntaxerror ใหม่ ('ฉันไม่ชอบไวยากรณ์ของคุณ');
โยน TypeError ใหม่ ('คุณใช้ตัวแปรประเภทใดที่จะพาฉันไป?');
โยน rangeerror ใหม่ ('ขออภัยคุณเพียงแค่ไม่ได้มีช่วง');
โยน EvalError ใหม่ ('ที่ไม่ได้ประเมิน');
โยน urierror ใหม่ ('uri นั่นคือคุณ?');
โยน referenceReRESS ใหม่ ('คุณไม่ได้/' ไม่อ้างถึงการอ้างอิงของคุณอย่างถูกต้อง ');
การใช้โซ่ต้นแบบยังสามารถสร้างประเภทข้อผิดพลาดที่กำหนดเองโดยการสืบทอดข้อผิดพลาด (โซ่ต้นแบบถูกนำมาใช้ในบทที่ 6) ณ จุดนี้คุณต้องระบุชื่อและแอตทริบิวต์ข้อความสำหรับประเภทข้อผิดพลาดที่สร้างขึ้นใหม่
เบราว์เซอร์ปฏิบัติต่อประเภทข้อผิดพลาดที่กำหนดเองที่สืบทอดมาจากข้อผิดพลาดเช่นเดียวกับประเภทข้อผิดพลาดอื่น ๆ การสร้างข้อผิดพลาดที่กำหนดเองนั้นมีประโยชน์หากคุณต้องการจับข้อผิดพลาดที่คุณโยนและปฏิบัติต่อมันแตกต่างจากข้อผิดพลาดของเบราว์เซอร์
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น CustomError (ข้อความ) {
this.name = 'customerror';
this.message = ข้อความ;
-
CustomError.prototype = ใหม่ข้อผิดพลาด ();
โยนใหม่ CustomError ('My Message');
เมื่อพบคำสั่งการโยนรหัสจะหยุดดำเนินการทันที รหัสจะดำเนินการต่อเพื่อดำเนินการต่อเมื่อคำสั่งลองจับจะจับค่าที่โยน
คำอธิบายโดยละเอียดเพิ่มเติมคือ: เมื่อมีการโยนข้อยกเว้นล่าม JavaScript จะหยุดการดำเนินการตามตรรกะในปัจจุบันและข้ามไปยังตัวจัดการข้อยกเว้นใกล้เคียง ตัวจัดการข้อยกเว้นเขียนไว้ในประโยคจับของคำสั่งลองจับ หากบล็อกรหัสที่โยนข้อยกเว้นไม่มีข้อจับที่เกี่ยวข้องล่ามจะตรวจสอบบล็อกรหัสปิดระดับสูงกว่าเพื่อดูว่ามีตัวจัดการข้อยกเว้นที่เกี่ยวข้องหรือไม่ และอื่น ๆ จนกว่าจะพบตัวจัดการข้อยกเว้น หากฟังก์ชั่นที่โยนข้อยกเว้นไม่ได้จัดการกับคำสั่งลองจับข้อยกเว้นจะถูกเผยแพร่ขึ้นไปยังรหัสที่เรียกฟังก์ชัน ด้วยวิธีนี้ข้อยกเว้นจะแพร่กระจายขึ้นไปตามโครงสร้างคำศัพท์ของวิธี JavaScript และสแต็กการโทร หากไม่พบตัวจัดการข้อยกเว้น JavaScript จะจัดการข้อยกเว้นเป็นข้อผิดพลาดของโปรแกรมและรายงานต่อผู้ใช้
ลองใช้คำสั่งจับและจับข้อผิดพลาด
ECMA-262 EDITION 3 แนะนำคำสั่ง Try-Catch เป็นวิธีมาตรฐานในการจัดการข้อยกเว้นใน JavaScript ซึ่งใช้ในการจับและจัดการกับข้อผิดพลาด
ในหมู่พวกเขาประโยคลองกำหนดบล็อกรหัสที่มีข้อยกเว้นที่ต้องดำเนินการอยู่ ประโยคจับตามมาตราลอง เมื่อมีข้อยกเว้นเกิดขึ้นที่ไหนสักแห่งในบล็อกลองใช้ตรรกะรหัสภายในการจับเรียกว่า ประโยคจับจะตามด้วยบล็อกในที่สุดที่วางรหัสทำความสะอาด ไม่ว่าจะมีข้อยกเว้นเกิดขึ้นในบล็อกลองหรือไม่ตรรกะภายในบล็อกในที่สุดจะถูกดำเนินการเสมอ แม้ว่าจะจับได้และในที่สุดก็เป็นทางเลือก แต่ประโยคลองใช้อย่างน้อยหนึ่งในสองเพื่อสร้างคำสั่งที่สมบูรณ์ด้วย
บล็อกคำสั่งลอง/catch/catch/ในที่สุดทั้งหมดจะต้องถูกล้อมรอบด้วยการจัดฟันแบบหยิก ต้องจัดฟันที่นี่ แม้ว่าจะมีคำสั่งเพียงคำเดียวในประโยค แต่ก็ไม่สามารถใช้งานจัดฟันได้
พยายาม{
// โดยทั่วไปการพูดรหัสที่นี่จะเริ่มตั้งแต่ต้นจนจบโดยไม่มีปัญหาใด ๆ
// แต่บางครั้งก็มีการโยนข้อยกเว้นไม่ว่าจะโยนโดยตรงโดยคำสั่งโยนหรือทางอ้อมโดยการเรียกวิธีการ
} catch (e) {
// ถ้าและเฉพาะในกรณีที่ข้อยกเว้นถูกโยนโดยบล็อกคำสั่งลองรหัสที่นี่จะถูกดำเนินการ
// ที่นี่คุณสามารถได้รับการอ้างอิงถึงวัตถุข้อผิดพลาดหรือค่าอื่น ๆ ที่ถูกโยนโดยตัวแปรโลคัล e
// บล็อกรหัสที่นี่สามารถจัดการข้อยกเว้นนี้ได้ด้วยเหตุผลบางอย่างหรือละเว้นข้อยกเว้นนี้และยังสามารถโยนข้อยกเว้นอีกครั้งผ่านคำสั่งการโยน
} ในที่สุด{
// ไม่ว่าคำสั่งลองจะมีข้อยกเว้นหรือไม่ตรรกะในที่สุดก็จะถูกดำเนินการเสมอ วิธีที่จะยุติบล็อกคำสั่งลองคือ:
// 1. สิ้นสุดตามปกติดำเนินการคำสั่งสุดท้ายของบล็อกคำสั่ง
// 2. ยุติการหยุดพักต่อหรือส่งคืนคำสั่ง
// 3. โยนข้อยกเว้นข้อยกเว้นถูกจับโดยประโยคจับ
// 4. โยนข้อยกเว้นข้อยกเว้นไม่ถูกจับยังคงเผยแพร่ต่อไป
-
โดยทั่วไปใส่รหัสทั้งหมดที่อาจโยนข้อผิดพลาดในบล็อกคำสั่งลองและใส่รหัสที่ใช้สำหรับการจัดการข้อผิดพลาดในบล็อก catch
หากรหัสใด ๆ ในข้อผิดพลาดบล็อกลองเกิดขึ้นกระบวนการดำเนินการรหัสจะถูกออกทันทีและจะดำเนินการบล็อก catch block ในเวลานี้บล็อกจับจะได้รับวัตถุที่มีข้อความแสดงข้อผิดพลาด ข้อมูลจริงที่มีอยู่ในวัตถุนี้จะแตกต่างจากเบราว์เซอร์ถึงเบราว์เซอร์ แต่ทั่วไปคือมีแอตทริบิวต์ข้อความที่เก็บข้อความแสดงข้อผิดพลาด
[หมายเหตุ] อย่าลืมตั้งชื่อวัตถุข้อผิดพลาด หากล้างมันจะมีการรายงานข้อผิดพลาดทางไวยากรณ์
การคัดลอกรหัสมีดังนี้:
พยายาม{
ถาม;
} catch (ข้อผิดพลาด) {
การแจ้งเตือน (error.message); // q ไม่ได้กำหนดไว้
-
// uncaught syntaxerror: โทเค็นที่ไม่คาดคิด)
พยายาม{
ถาม;
}จับ(){
การแจ้งเตือน (error.message);
-
Catch ยอมรับพารามิเตอร์ที่ระบุค่าที่โยนโดยบล็อกโค้ดลอง
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น throwit (ข้อยกเว้น) {
พยายาม {
โยนข้อยกเว้น;
} catch (e) {
console.log ('จับ:'+ e);
-
-
Throwit (3); // จับ: 3
throwit ('hello'); // catch: สวัสดี
Throwit (ข้อผิดพลาดใหม่ ('เกิดข้อผิดพลาดเกิดขึ้น')); // จับ: ข้อผิดพลาด: เกิดข้อผิดพลาดเกิดขึ้น
หลังจากบล็อกจับรหัสจับข้อผิดพลาดโปรแกรมจะไม่ถูกขัดจังหวะและจะดำเนินการต่อไปตามกระบวนการปกติ
การคัดลอกรหัสมีดังนี้:
พยายาม{
โยน "ข้อผิดพลาด";
} catch (e) {
console.log (111);
-
console.log (222);
// 111
// 222
เพื่อที่จะจับข้อผิดพลาดประเภทต่าง ๆ สามารถเพิ่มคำสั่งการตัดสินลงในบล็อกรหัสจับ
การคัดลอกรหัสมีดังนี้:
พยายาม {
foo.bar ();
} catch (e) {
if (e instanceof everror) {
console.log (e.name + ":" + e.message);
} อื่นถ้า (e instanceof rangeerror) {
console.log (e.name + ":" + e.message);
-
-
-
แม้ว่าประโยคในที่สุดจะเป็นตัวเลือกในคำสั่งลองจับ แต่เมื่อใช้ประโยคในที่สุดรหัสจะถูกดำเนินการไม่ว่าจะเกิดอะไรขึ้น กล่าวอีกนัยหนึ่งรหัสทั้งหมดในบล็อกคำสั่งลองจะถูกดำเนินการตามปกติและในที่สุดก็จะถูกดำเนินการ หากบล็อกคำสั่ง Catch ถูกดำเนินการเนื่องจากข้อผิดพลาดประโยคสุดท้ายจะยังคงถูกดำเนินการ ตราบใดที่รหัสมีคำสั่งในที่สุดไม่ว่ารหัสใดที่มีอยู่ในบล็อกคำสั่งลองหรือจับ - หรือแม้แต่คำสั่ง Return การดำเนินการของประโยคในที่สุดจะไม่ถูกป้องกัน
การคัดลอกรหัสมีดังนี้:
// ข้อผิดพลาดไม่ได้ถูกจับเพราะไม่มีบล็อกคำสั่งจับ หลังจากดำเนินการบล็อกรหัสในที่สุดโปรแกรมจะถูกขัดจังหวะเมื่อเกิดข้อผิดพลาด
ฟังก์ชั่น Cleansup () {
พยายาม {
โยนข้อผิดพลาดใหม่ ('ข้อผิดพลาด ... ');
console.log ('บรรทัดนี้จะไม่ถูกดำเนินการ');
} ในที่สุด {
console.log ('งานทำความสะอาดที่สมบูรณ์');
-
-
Cleansup ();
// ทำงานทำความสะอาดให้เสร็จสมบูรณ์
// ข้อผิดพลาด: มีบางอย่างผิดปกติ ...
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น testfinnally () {
พยายาม{
กลับ 2;
} catch (ข้อผิดพลาด) {
กลับ 1;
} ในที่สุด{
กลับ 0;
-
-
testfinnally (); // 0
[หมายเหตุ] ค่าของการนับของคำสั่ง Return จะได้รับก่อนที่จะเรียกใช้บล็อกรหัสสุดท้าย
การคัดลอกรหัสมีดังนี้:
count var = 0;
ฟังก์ชั่นการนับ () {
พยายาม {
นับคืน;
} ในที่สุด {
นับ ++;
-
-
countup (); // 0
console.log (นับ); // 1
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น f () {
พยายาม {
console.log (0);
โยน "บั๊ก";
} catch (e) {
console.log (1);
กลับมาจริง; // ประโยคนี้จะล่าช้าไปจนกระทั่งสิ้นสุดบล็อกรหัสสุดท้ายก่อนที่จะดำเนินการ
console.log (2); // จะไม่ทำงาน
} ในที่สุด {
console.log (3);
กลับเท็จ; // ประโยคนี้จะครอบคลุมผลตอบแทนก่อนหน้านี้
console.log (4); // จะไม่ทำงาน
-
console.log (5); // จะไม่ทำงาน
-
var result = f ();
// 0
// 1
// 3
console.log (ผลลัพธ์); // false
【เคล็ดลับ】ขอบเขตระดับบล็อก
การใช้คำสั่งลองจับทั่วไปคือการสร้างขอบเขตระดับบล็อกซึ่งตัวแปรที่ประกาศใช้นั้นถูกต้องภายในการจับเท่านั้น
ES6 แนะนำคำหลักเพื่อสร้างขอบเขตระดับบล็อกสำหรับตัวแปรที่ประกาศ อย่างไรก็ตามในสถานการณ์ปัจจุบันของ ES3 และ ES5 คำสั่งลองจับมักจะใช้เพื่อให้ได้เอฟเฟกต์ที่คล้ายกัน
จากรหัสต่อไปนี้ E มีอยู่ภายในประโยคจับเท่านั้นและข้อผิดพลาดจะถูกโยนลงเมื่อพยายามอ้างอิงจากที่อื่น
การคัดลอกรหัสมีดังนี้:
พยายาม{
โยนข้อผิดพลาดใหม่ (); // ข้อผิดพลาดด้านบน
} catch (e) {
console.log (e); // ข้อผิดพลาด (…)
-
console.log (e); // uncaught ReferenceError: E ไม่ได้กำหนดไว้
ข้อผิดพลาดทั่วไป
แกนหลักของการจัดการข้อผิดพลาดคือการทราบก่อนว่าข้อผิดพลาดจะเกิดขึ้นในรหัส เนื่องจาก JavaScript ถูกพิมพ์อย่างหลวม ๆ และไม่ได้ตรวจสอบพารามิเตอร์ของฟังก์ชันข้อผิดพลาดจะเกิดขึ้นในระหว่างรหัสเท่านั้น โดยทั่วไปการพูดจะต้องให้ความสนใจกับ: พิมพ์ข้อผิดพลาดในการแปลง, ข้อผิดพลาดชนิดข้อมูลและข้อผิดพลาดในการสื่อสาร
【พิมพ์ข้อผิดพลาดการแปลง】
พิมพ์ข้อผิดพลาดการแปลงเกิดขึ้นเมื่อใช้ตัวดำเนินการหรือใช้โครงสร้างภาษาอื่นของประเภทข้อมูลที่อาจแปลงค่าโดยอัตโนมัติ
คำสั่งควบคุมการไหลมีแนวโน้มที่จะพิมพ์ข้อผิดพลาดการแปลง คำสั่งเช่นถ้าจะแปลงค่าใด ๆ เป็นบูลีนโดยอัตโนมัติก่อนที่จะพิจารณาการดำเนินการถัดไป โดยเฉพาะอย่างยิ่งหากมีคำสั่งหากใช้อย่างไม่เหมาะสมพวกเขามักจะทำผิดพลาด
ตัวแปรชื่อที่ไม่ได้ใช้จะถูกกำหนดค่าที่ไม่ได้กำหนดโดยอัตโนมัติ ค่าที่ไม่ได้กำหนดสามารถแปลงเป็นเท็จค่าบูลีนดังนั้นคำสั่ง IF ในฟังก์ชั่นต่อไปนี้จะใช้ได้เฉพาะกับกรณีที่มีพารามิเตอร์ที่สาม ปัญหาคือไม่เพียง แต่ไม่ได้กำหนดจะถูกแปลงเป็นเท็จและไม่ได้เป็นเพียงค่าสตริงที่สามารถแปลงเป็นจริงได้ ตัวอย่างเช่นหากพารามิเตอร์ที่สามคือค่า 0 การทดสอบของคำสั่ง IF จะล้มเหลวและการทดสอบค่าลอการิทึม 1 จะผ่านไป
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น concat (str1, str2, str3) {
var result = str1 + str2;
ถ้า (str3) {// ไม่ชอบสิ่งนี้อย่างแน่นอน
ผลลัพธ์ += str3;
-
ผลการกลับมา;
-
การใช้ค่าที่ไม่ใช่ boolean ในคำสั่งควบคุมการไหลเป็นแหล่งที่มาของข้อผิดพลาดที่พบบ่อยมาก เพื่อหลีกเลี่ยงข้อผิดพลาดดังกล่าวจำเป็นต้องส่งผ่านค่าบูลีนเมื่อเปรียบเทียบเงื่อนไข ในความเป็นจริงการดำเนินการเปรียบเทียบบางรูปแบบสามารถบรรลุเป้าหมายนี้ได้
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น concat (str1, str2, str3) {
var result = str1 + str2;
if (typeof str3 == 'string') {// เหมาะสมกว่า
ผลลัพธ์ += str3;
-
ผลการกลับมา;
-
【ข้อผิดพลาดประเภทข้อมูล】
JavaScript ถูกพิมพ์อย่างหลวม ๆ และจะไม่ถูกนำมาเปรียบเทียบเพื่อให้แน่ใจว่าชนิดข้อมูลของพวกเขาถูกต้องจนกว่าจะใช้ตัวแปรและพารามิเตอร์ฟังก์ชัน เพื่อให้แน่ใจว่าข้อผิดพลาดของประเภทข้อมูลจะไม่เกิดขึ้นสามารถเขียนรหัสการตรวจจับชนิดข้อมูลที่เหมาะสมเท่านั้น ข้อผิดพลาดของประเภทข้อมูลมีแนวโน้มที่จะเกิดขึ้นมากที่สุดเมื่อผ่านค่าที่ไม่คาดคิดไปยังฟังก์ชันการพล็อต
การคัดลอกรหัสมีดังนี้:
// ฟังก์ชั่นที่ไม่ปลอดภัยค่าที่ไม่ใช่อาเรย์ใด ๆ จะทำให้เกิดข้อผิดพลาด
ฟังก์ชั่น reversesort (ค่า) {
ถ้า (ค่า) {
ค่า. sort ();
ค่า. Reverse ();
-
-
ข้อผิดพลาดทั่วไปอีกประการหนึ่งคือการเปรียบเทียบพารามิเตอร์กับค่า NULL เมื่อเปรียบเทียบกับ NULL เท่านั้นทำให้มั่นใจได้ว่าค่าที่สอดคล้องกันจะไม่เป็นโมฆะและไม่ได้กำหนด เพื่อให้แน่ใจว่าค่าที่ส่งผ่านนั้นถูกต้องไม่เพียงพอที่จะตรวจจับค่า NULL เท่านั้น
การคัดลอกรหัสมีดังนี้:
// ฟังก์ชั่นที่ไม่ปลอดภัยค่าที่ไม่ใช่อาเรย์ใด ๆ จะทำให้เกิดข้อผิดพลาด
ฟังก์ชั่น reversesort (ค่า) {
ถ้า (ค่า! = null) {
ค่า. sort ();
ค่า. Reverse ();
-
-
หากวัตถุที่มีวิธีการเรียงลำดับ () (แทนที่จะเป็นอาร์เรย์) มันจะผ่านการตรวจจับ แต่ข้อผิดพลาดอาจเกิดขึ้นเมื่อเรียกใช้ฟังก์ชันย้อนกลับ ()
การคัดลอกรหัสมีดังนี้:
// ฟังก์ชั่นที่ไม่ปลอดภัยค่าที่ไม่ใช่อาเรย์ใด ๆ จะทำให้เกิดข้อผิดพลาด
ฟังก์ชั่น reversesort (ค่า) {
if (typeof value.sort == 'function') {
ค่า. sort ();
ค่า. Reverse ();
-
-
ในกรณีที่คุณรู้ว่าคุณควรผ่านประเภทใดควรใช้อินสแตนซ์ของการตรวจจับประเภทข้อมูลของมัน
การคัดลอกรหัสมีดังนี้:
// ปลอดภัยค่าที่ไม่ใช่อาร์เรย์จะถูกละเว้น
ฟังก์ชั่น reversesort (ค่า) {
if (ค่าอินสแตนซ์ของอาร์เรย์) {
ค่า. sort ();
ค่า. Reverse ();
-
-
【ข้อผิดพลาดในการสื่อสาร】
ด้วยการเขียนโปรแกรม AJAX ที่เพิ่มขึ้นมันเป็นเรื่องธรรมดาสำหรับเว็บแอปพลิเคชันในการโหลดข้อมูลหรือฟังก์ชั่นแบบไดนามิกในช่วงวงจรชีวิตของพวกเขา อย่างไรก็ตามการสื่อสารระหว่าง JavaScript และเซิร์ฟเวอร์อาจทำให้เกิดข้อผิดพลาด
ปัญหาที่พบบ่อยที่สุดคือข้อมูลไม่ได้เข้ารหัสโดยใช้ encodeuricomponent () ก่อนส่งไปยังเซิร์ฟเวอร์
การคัดลอกรหัสมีดังนี้:
//ความผิดพลาด
http://www.yourdomain.com/?redir=http://www.sometherdomain.com?a=b&c=d
// การเรียก encodeuricomponent () สำหรับสตริงทั้งหมดหลังจาก 'redir =' สามารถแก้ปัญหานี้ได้
http://www.yourdomain.com/?