JavaScript có thể gặp lỗi trong quá trình chạy, gây ra tình trạng chương trình không hoạt động như mong đợi. Để xử lý những lỗi này, JavaScript cung cấp 3 công cụ chính:
- try: Khối code được đặt bên trong try sẽ được thực thi đầu tiên.
- catch: Nếu một lỗi xảy ra bên trong khối try, nó sẽ được bắt bởi khối catch và xử lý tại đây. Mỗi catch có thể xử lý một loại lỗi cụ thể.
- finally: Bất kể có lỗi hay không, khối finally sẽ luôn được thực thi cuối cùng. Nó thường dùng để dọn dẹp tài nguyên (ví dụ: đóng kết nối mạng, giải phóng bộ nhớ).
Nói một cách đơn giản hơn, bạn có thể hiểu như sau:
- try: Hãy thử chạy đoạn code này xem sao.
- catch: Nếu xảy ra lỗi, hãy làm thế này.
- finally: Dù có lỗi hay không, cuối cùng cũng phải làm thế này.
Bắt lỗi trong Javascript
Khi chạy code Javascript, có thể xảy ra nhiều lỗi khác nhau. Chúng có thể là lỗi do lập trình viên viết sai, lỗi do người dùng nhập sai dữ liệu hoặc những lỗi không thể lường trước được.
Cú pháp try và catch trong Javascript.
- try: Cho phép bạn xác định một khối code để kiểm tra lỗi trong quá trình thực thi.
- catch: Cho phép bạn xác định một khối code sẽ được thực thi nếu xảy ra lỗi trong khối try.
Cặp try và catch được sử dụng như sau:
try {
// Khối code cần kiểm tra lỗi
} catch(err) {
// Khối code xử lý lỗi
}
Trong ví dụ này, chúng ta cố tình viết sai từ “alert” thành “adddlert” để tạo ra lỗi:
<p id="demo"></p>
<script>
try {
adddlert("Welcome guest!");
} catch(err) {
document.getElementById("demo").innerHTML = err.message;
}
</script>
Khi chạy đoạn code này, JavaScript sẽ bắt lỗi “adddlert” và thực thi khối catch để xử lý nó.
Lệnh throw trong JavaScript.
Throw là một câu lệnh trong JavaScript cho phép bạn tạo ra lỗi tùy chỉnh. Về mặt kỹ thuật, bạn có thể hiểu nó là tạo ra một ngoại lệ (throw an exception).
- Ngoại lệ có thể là:
- Chuỗi JavaScript (String)
- Số (Number)
- Giá trị đúng/sai (Boolean)
- Đối tượng (Object)
Ví dụ cách khai báo như sau, câu lệnh throw "Quá lớn";
sẽ tạo ra một ngoại lệ có thông báo là “Quá lớn”. Ngoại lệ này sẽ được xử lý bởi khối lệnh catch
ngay sau đó. Câu lệnh throw 500;
sẽ tạo ra một ngoại lệ có giá trị là 500. Ngoại lệ này cũng sẽ được xử lý bởi khối lệnh catch
.
throw "Quá lớn"; // Tạo ra ngoại lệ là một chuỗi
throw 500; // Tạo ra ngoại lệ là một số
Ví dụ cách áp dụng.
let num = 100;
try {
if (num > 100) {
throw "Quá lớn";
}
} catch (err) {
console.log(err.message);
}
Kết quả:
Quá lớn
Trong ví dụ này, câu lệnh if
sẽ kiểm tra xem số num
có lớn hơn 100 hay không. Nếu đúng, câu lệnh throw "Quá lớn";
sẽ được thực thi và tạo ra một ngoại lệ có thông báo là “Quá lớn”. Ngoại lệ này sẽ được xử lý bởi khối lệnh catch
, và dòng console.log(err.message);
sẽ in thông báo lỗi “Quá lớn” ra console.
Kết hợp throw cùng với try và catch.
Nếu bạn sử dụng throw cùng với try và catch, bạn có thể kiểm soát luồng chương trình và tạo ra các thông báo lỗi tùy chỉnh.
Ví dụ này kiểm tra đầu vào của người dùng. Nếu giá trị không hợp lệ, một ngoại lệ (err) sẽ được thông báo. Ngoại lệ (err) này sẽ được bắt bởi khối catch và hiển thị thông báo lỗi tùy chỉnh:
<!DOCTYPE html>
<html>
<body>
<p>Vui lòng nhập số từ 5 đến 10:</p>
<input id="demo" type="text">
<button type="button" onclick="myFunction()">Kiểm tra đầu vào</button>
<p id="p01"></p>
<script>
function myFunction() {
const message = document.getElementById("p01");
message.innerHTML = "";
let x = document.getElementById("demo").value;
try {
if (x.trim() === "") throw "trống";
if (isNaN(x)) throw "không phải số";
x = Number(x);
if (x < 5) throw "quá nhỏ";
if (x > 10) throw "quá lớn";
} catch(err) {
message.innerHTML = "Đầu vào " + err;
}
}
</script>
</body>
</html>
Xác thực HTML.
Các trình duyệt hiện nay thường sử dụng kết hợp JavaScript và xác thực HTML tích hợp, sử dụng các quy tắc xác thực được xác định trước trong các thuộc tính HTML:
<input id="demo" type="number" min="5" max="10" step="1">
Bạn có thể tìm hiểu thêm về xác thực biểu mẫu trong các bài sau.
Câu lệnh finally.
Câu lệnh finally cho phép bạn thực thi code, sau try và catch, bất kể kết quả là gì:
Cú pháp:
try {
// Khối code để thử
} catch(err) {
// Khối code để xử lý lỗi
} finally {
// Khối code được thực thi bất kể kết quả của try / catch
}
Ví dụ:
function myFunction() {
const message = document.getElementById("p01");
message.innerHTML = "";
let x = document.getElementById("demo").value;
try {
if (x.trim() === "") throw "trống";
if (isNaN(x)) throw "không phải số";
x = Number(x);
if (x > 10) throw "quá lớn";
if (x < 5) throw "quá nhỏ";
} catch(err) {
message.innerHTML = "Lỗi: " + err + ".";
} finally {
document.getElementById("demo").value = "";
}
}
Đối tượng Error trong JavaScript.
JavaScript có một đối tượng Error tích hợp sẵn cung cấp thông tin về lỗi khi xảy ra. Đối tượng này có hai thuộc tính hữu ích: name và message.
Thuộc tính của đối tượng Error:
Thuộc tính | Mô tả |
---|---|
name | Thiết lập hoặc trả về tên lỗi |
message | Thiết lập hoặc trả về thông báo lỗi (chuỗi) |
Các giá trị của thuộc tính Error Name.
Sáu giá trị khác nhau có thể được trả về bởi thuộc tính name của lỗi:
Tên lỗi | Mô tả |
---|---|
EvalError | Đã xảy ra lỗi trong hàm eval(). |
RangeError | Đã xảy ra lỗi “ngoài phạm vi”. |
ReferenceError | Đã xảy ra lỗi tham chiếu bất hợp pháp. |
SyntaxError | Đã xảy ra lỗi cú pháp. |
TypeError | Đã xảy ra lỗi kiểu. |
URIError | Đã xảy ra lỗi trong hàm encodeURI(). |
Sáu giá trị khác nhau được mô tả bên dưới như sau:
- Lỗi Eval:
- EvalError cho biết một lỗi trong hàm eval()
- Các phiên bản JavaScript mới hơn không tạo ra EvalError. Thay vào đó, hãy sử dụng SyntaxError.
Lỗi Range
RangeError sẽ được tạo ra nếu bạn sử dụng một số nằm ngoài phạm vi giá trị hợp lệ.
Ví dụ: Bạn không thể đặt số chữ số có nghĩa của một số thành 500.
let num = 1;
try {
num.toPrecision(500); // A number cannot have 500 significant digits
} catch(err) {
document.getElementById("demo").innerHTML = err.name;
}
Lỗi tham chiếu
ReferenceError sẽ được ném nếu bạn sử dụng (tham chiếu) một biến chưa được khai báo:
let x = 5;
try {
x = y + 1; // y cannot be used (referenced)
} catch(err) {
document.getElementById("demo").innerHTML = err.name;
}
Lỗi Cú Pháp Một SyntaxError sẽ được tạo ra ra nếu bạn cố gắng đánh giá mã có lỗi cú pháp.
Ví dụ.
try {
eval("alert('Xin chào)"); // Thiếu dấu ' sẽ tạo ra một lỗi
}
catch(err) {
document.getElementById("demo").innerHTML = err.name;
}
Lỗi Loại (TypeError) Một TypeError sẽ được tạo ra ra nếu bạn sử dụng một giá trị nằm ngoài phạm vi của các loại dữ liệu mong đợi:
Ví dụ
let num = 1;
try {
num.toUpperCase(); // Bạn không thể chuyển đổi một số thành chữ in hoa
}
catch(err) {
document.getElementById("demo").innerHTML = err.name;
}
Lỗi URI (Uniform Resource Identifier) Một URIError sẽ được tạo ra ra nếu bạn sử dụng ký tự không hợp lệ trong một hàm URI:
Ví dụ
try {
decodeURI("%%%"); // Bạn không thể giải mã URI ký tự phần trăm
}
catch(err) {
document.getElementById("demo").innerHTML = err.name;
}
Các thuộc tính không chuẩn của đối tượng lỗi trong JavaScript.
Thuộc tính không chuẩn là một thuộc tính được định nghĩa bởi một nhà cung cấp hoặc tổ chức cụ thể, nhưng không được định nghĩa bởi tiêu chuẩn chính thức. Các thuộc tính không chuẩn thường được sử dụng để cung cấp thêm chức năng hoặc thông tin cho một đối tượng hoặc API cụ thể.
Trong trường hợp của JavaScript, các thuộc tính không chuẩn của đối tượng lỗi được định nghĩa bởi Mozilla và Microsoft. Các thuộc tính này không được hỗ trợ bởi tất cả các trình duyệt, nhưng chúng có thể hữu ích để cung cấp thêm thông tin về lỗi.
Ví dụ, thuộc tính fileName
chứa tên tệp chứa mã gây ra lỗi. Thuộc tính này có thể hữu ích để gỡ lỗi khi bạn không chắc chắn mã ở đâu gây ra lỗi.
Thuộc tính lineNumber
chứa số dòng trong tệp chứa mã gây ra lỗi. Thuộc tính này cũng có thể hữu ích để gỡ lỗi.
Các thuộc tính không chuẩn có thể hữu ích, nhưng bạn nên lưu ý rằng chúng không được hỗ trợ bởi tất cả các trình duyệt. Nếu bạn đang phát triển ứng dụng cho một đối tượng rộng rãi người dùng, bạn nên tránh sử dụng các thuộc tính không chuẩn.
Các thuộc tính không chuẩn của đối tượng lỗi trong JavaScript bao gồm:
- fileName: Tên tệp chứa mã gây ra lỗi.
- lineNumber: Số dòng trong tệp chứa mã gây ra lỗi.
- columnNumber: Số cột trong tệp chứa mã gây ra lỗi.
- stack: Một chuỗi chứa thông tin về ngăn xếp gọi khi lỗi xảy ra.
- description: Một chuỗi mô tả lỗi.
- number: Một số nguyên đại diện cho loại lỗi.
Ví dụ:
let num = 1;
try {
num = y + 1; // y cannot be used (referenced)
} catch (err) {
console.log(err.fileName);
console.log(err.lineNumber);
console.log(err.columnNumber);
console.log(err.stack);
console.log(err.description);
console.log(err.number);
}
Kết quả:
index.js
11
1
Error: ReferenceError: y is not defined
at index.js:11:1
at eval (eval at <anonymous>:2:1)
at <anonymous>:1:1
1
ReferenceError
Trong ví dụ này, câu lệnh num = y + 1;
sẽ gây ra lỗi ReferenceError vì biến y
chưa được khai báo. Khi lỗi xảy ra, đối tượng lỗi sẽ được tạo ra và các thuộc tính không chuẩn của nó sẽ được đặt.
Cụ thể, các giá trị của các thuộc tính không chuẩn trong ví dụ này là:
- fileName:
index.js
- lineNumber:
11
- columnNumber:
1
- stack:
Error: ReferenceError: y is not defined at index.js:11:1 at eval (eval at <anonymous>:2:1) at <anonymous>:1:1
- description:
ReferenceError: y is not defined
- number:
1
Bạn có thể sử dụng các thuộc tính không chuẩn này để cung cấp thêm thông tin về lỗi cho người dùng hoặc để gỡ lỗi chương trình của bạn.