Sự khác biệt giữa `throw new Error` và` throw someObject` là gì?


378

Tôi muốn viết một trình xử lý lỗi phổ biến sẽ bắt lỗi tùy chỉnh được ném vào mục đích tại bất kỳ trường hợp nào của mã.

Khi tôi đã throw new Error('sample')thích như sau trong đoạn mã sau

try {
    throw new Error({'hehe':'haha'});
    // throw new Error('hehe');
} catch(e) {
    alert(e);
    console.log(e);
}

Nhật ký hiển thị trong Firefox Error: [object Object]và tôi không thể phân tích đối tượng.

Trong lần thứ hai throw, nhật ký hiển thị là:Error: hehe

Trong khi đó tôi đã làm

try {
    throw ({'hehe':'haha'});
} catch(e) {
    alert(e);
    console.log(e);
}

Bảng điều khiển hiển thị như sau: Object { hehe="haha"}trong đó tôi có thể truy cập các thuộc tính lỗi.

Sự khác biệt là gì?

Là sự khác biệt như đã thấy trong mã? Like chuỗi sẽ chỉ được truyền dưới dạng chuỗi và đối tượng là đối tượng nhưng cú pháp sẽ khác nhau?

Tôi chưa khám phá ra việc ném lỗi đối tượng, tôi đã thực hiện chỉ ném dây.

Có cách nào khác ngoài hai phương pháp nêu trên không?


6
Vấn đề với lỗi ném mới ({prop: val}) không phải là lỗi xây dựng hợp lệ. Lỗi có các thuộc tính được thảo luận bởi Hemant.
Grantwparks

Câu trả lời:


216

Dưới đây là một lời giải thích tốt về đối tượng Lỗi và ném lỗi của riêng bạn

Đối tượng lỗi

Chỉ là những gì chúng ta có thể trích xuất từ ​​nó trong trường hợp có lỗi? Đối tượng Error trong tất cả các trình duyệt hỗ trợ hai thuộc tính sau:

  • Tên: Tên của lỗi, hay cụ thể hơn là tên của hàm xây dựng mà lỗi thuộc về.

  • message: Một mô tả về lỗi, với mô tả này thay đổi tùy theo trình duyệt.

Sáu giá trị có thể có thể được trả về bởi thuộc tính name, như đã đề cập tương ứng với tên của các hàm tạo của lỗi. Họ đang:

Error Name          Description

EvalError           An error in the eval() function has occurred.

RangeError          Out of range number value has occurred.

ReferenceError      An illegal reference has occurred.

SyntaxError         A syntax error within code inside the eval() function has occurred.
                    All other syntax errors are not caught by try/catch/finally, and will
                    trigger the default browser error message associated with the error. 
                    To catch actual syntax errors, you may use the onerror event.

TypeError           An error in the expected variable type has occurred.

URIError            An error when encoding or decoding the URI has occurred 
                   (ie: when calling encodeURI()).

Ném lỗi của riêng bạn (ngoại lệ)

Thay vì chờ đợi một trong 6 loại lỗi xảy ra trước khi điều khiển được tự động chuyển từ khối thử sang khối bắt, bạn cũng có thể ném ngoại lệ của mình một cách rõ ràng để buộc điều đó xảy ra theo yêu cầu. Điều này rất tốt cho việc tạo các định nghĩa của riêng bạn về lỗi là gì và khi nào nên chuyển điều khiển để bắt.


4
ồ vâng đây là một trong những điều tốt mà tôi đã bỏ lỡ trước khi đặt câu hỏi này dù sao người dùng đang tìm kiếm thông tin liên quan đến điều này sẽ bị xóa. Bây giờ tôi rõ ràng những gì là những gì. :) Cảm ơn bạn. Tôi sẽ trở lại để bỏ phiếu trong một vài ngày.
Jayapal Chandran

184
Thậm chí không trả lời câu hỏi nhưng câu trả lời được đánh giá cao nhất?
dùng9993

@ user9993 Câu hỏi ho người dùng đang tìm kiếm sự hiểu biết chi tiết theo cuộc trò chuyện tại thời điểm đó, vì vậy câu trả lời phù hợp đã được cung cấp và hữu ích cho người dùng. đó là lý do để được chấp nhận và hầu hết các phiếu bầu.
Hemant Metalia

5
@HemantMetalia Nhưng anh ấy đúng, câu trả lời cho thấy thậm chí không phải là nỗ lực nhỏ nhất để trả lời câu hỏi của OP như đã nêu. Nếu một số câu trả lời rất khác nhau trong trò chuyện đã được trả lời nên vẫn còn trong trò chuyện, thì ở đây câu hỏi và câu trả lời không có kết nối logic nào.
Mörre

Và để trả lời câu hỏi ban đầu, nó không thành vấn đề với Javascript. Tuy nhiên, Error(và các lớp con) được sử dụng theo quy ước. Theo mặc định, chúng cũng cung cấp một thuộc tính ngăn xếp, mặc dù điều đó có thể được thêm vào thủ công. Vì vậy, nó thực sự chủ yếu là quy ước, dòng chương trình không bị ảnh hưởng bởi những gì bạn ném, chỉ là bạn có throwvấn đề. Bạn có thể throw "grandmother down the stairs";và nó sẽ hoạt động như nhau, ngoại trừ việc sẽ không có chức năng xử lý lỗi và theo dõi ngăn xếp đính kèm, các phóng viên, trình gỡ lỗi mong đợi Errorhoặc các thuộc tính đi kèm, chính xác hơn.
Mörre

104

ném "tôi ác"

throwsẽ chấm dứt thực hiện thêm & phơi bày chuỗi thông báo khi bắt lỗi.

try {
  throw "I'm Evil"
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e); //I'm Evil
}

Bảng điều khiển sau khi ném sẽ không bao giờ đạt được nguyên nhân chấm dứt.


ném lỗi mới ("Tôi rất ngọt ngào")

throw new Errorphơi bày một sự kiện lỗi với hai thông số tênthông báo . Nó cũng chấm dứt thực hiện thêm

try {
  throw new Error("I'm Evil")
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e.name, e.message); //Error, I'm Evil
}


16
những gì về sự khác biệt giữa "ném lỗi ('bất cứ điều gì')" và "ném lỗi mới ('bất cứ điều gì')" - cả hai đều hoạt động.
joedotnot

9
Lỗi là chức năng, Lỗi mới là một nhà xây dựng. cả hai đều hoạt động giống nhau developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
mẹo

5
@NishchitDhanani Tôi thấy lạ là một bình luận không thể giải mã và sai như vậy lại được nâng cấp. Cả "Lỗi là chức năng", cũng không phải "Lỗi mới là nhà xây dựng" hoàn toàn không có ý nghĩa và / hoặc sai. Trong bối cảnh đó, không rõ chính xác liên kết nào được cho là "chứng minh". Đây là trang MDN Error, được rồi, kết nối đến bình luận ở đâu? Một nửa số người bình luận và trả lời câu hỏi của OP nên chỉ im lặng.
Mörre

@ Mörre Xem phần này Used as a functiontừ liên kết này ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Kẻ

Được rồi, tôi hiểu rồi. Đó là một chức năng .
Nishchit Dhanani

73

Bài viết sau đây có lẽ đi sâu vào chi tiết hơn là lựa chọn tốt hơn; throw 'An error'hoặc throw new Error('An error'):

http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

Nó gợi ý rằng cái sau ( new Error()) đáng tin cậy hơn, vì các trình duyệt như Internet Explorer và Safari (không chắc chắn về các phiên bản) không báo cáo chính xác thông báo khi sử dụng cái trước.

Làm như vậy sẽ gây ra lỗi, nhưng không phải tất cả các trình duyệt đều phản hồi theo cách bạn mong đợi. Mỗi Firefox, Opera và Chrome đều hiển thị một thông báo ngoại lệ chưa được phát hiện và sau đó bao gồm chuỗi tin nhắn. Safari và Internet Explorer chỉ đơn giản là đưa ra một lỗi ngoại lệ chưa được phát hiện trên mạng và không cung cấp chuỗi thông báo. Rõ ràng, đây là tối ưu từ quan điểm gỡ lỗi.


36

Trước tiên bạn đề cập đến mã này:

throw new Error('sample')

và sau đó trong ví dụ đầu tiên bạn viết:

throw new Error({'hehe':'haha'}) 

Đối tượng Lỗi đầu tiên thực sự sẽ hoạt động, vì nó đang mong đợi một giá trị chuỗi, trong trường hợp này là 'mẫu'. Thứ hai sẽ không bởi vì bạn đang cố gắng truyền một đối tượng vào và nó đang mong đợi một chuỗi.

Đối tượng lỗi sẽ có thuộc tính "thông báo", đó là 'mẫu'.


12
Cái thứ hai không hoạt động, chỉ là không phải là một cách rất hữu ích. Nó thực thi toString()phương thức trên đối tượng được truyền vào, dẫn đến [object Object]lỗi (như Op đã viết).
cjn


15

bạn có thể throwlà đối tượng

throw ({message: 'This Failed'})

sau đó ví dụ trong try/catch

try {
//
} catch(e) {
    console.log(e); //{message: 'This Failed'}
    console.log(e.message); //This Failed
}

hoặc chỉ ném một chuỗi lỗi

throw ('Your error')

try {
//
} catch(e) {
    console.log(e); //Your error
}

throw new Error //only accept a string

15

Hàm Errortạo được sử dụng để tạo một đối tượng lỗi. Các đối tượng lỗi được ném khi xảy ra lỗi thời gian chạy. Đối tượng Error cũng có thể được sử dụng làm đối tượng cơ sở cho các trường hợp ngoại lệ do người dùng xác định.

Lỗi do người dùng định nghĩa được ném qua throwcâu lệnh. điều khiển chương trình sẽ được chuyển đến catchkhối đầu tiên trong ngăn xếp cuộc gọi.

Sự khác biệt giữa ném lỗi có và không có đối tượng Lỗi:


throw {'hehe':'haha'};

Trong chrome devtools trông như thế này:

nhập mô tả hình ảnh ở đây

Chrome nói với chúng tôi rằng chúng tôi có một lỗi chưa được phát hiện, đó chỉ là một đối tượng JS. Bản thân đối tượng có thể có thông tin liên quan đến lỗi nhưng chúng tôi vẫn không biết ngay lập tức nó đến từ đâu. Không hữu ích lắm khi chúng ta đang làm việc với mã của mình và gỡ lỗi nó.


throw new Error({'hehe':'haha'}); 

Trong chrome devtools trông như thế này:

nhập mô tả hình ảnh ở đây

Một lỗi được ném với đối tượng Error cung cấp cho chúng ta dấu vết ngăn xếp khi chúng ta mở rộng nó. Điều này cung cấp cho chúng tôi thông tin có giá trị trong đó lỗi chính xác xuất phát từ đó thường là thông tin có giá trị khi gỡ lỗi mã của bạn. Lưu ý thêm rằng lỗi cho biết [object Object], điều này là do hàm Errortạo dự kiến ​​một chuỗi thông báo là đối số đầu tiên. Khi nó nhận được một đối tượng, nó sẽ ép nó thành một chuỗi.


2

Phản ứng hành vi

Ngoài các câu trả lời còn lại, tôi muốn chỉ ra một điểm khác biệt trong React.

Nếu tôi ném new Error()và tôi đang ở chế độ phát triển, tôi sẽ nhận được màn hình lỗi và nhật ký giao diện điều khiển. Nếu tôi ném một chuỗi ký tự, tôi sẽ chỉ nhìn thấy nó trong bảng điều khiển và có thể bỏ lỡ nó, nếu tôi không xem nhật ký giao diện điều khiển.

Thí dụ

Ném một bản ghi lỗi vào bảng điều khiển hiển thị màn hình lỗi trong khi ở chế độ phát triển (màn hình sẽ không hiển thị trong sản xuất).

throw new Error("The application could not authenticate.");

Màn hình lỗi trong phản ứng

Trong khi đó đoạn mã sau chỉ đăng nhập vào bàn điều khiển:

throw "The application could not authenticate.";
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.