2012-01-24 25 views
14

Tôi bắt đầu học JavaScript, cho đến nay không có vấn đề gì nhưng tôi gặp khó khăn trong việc tìm kiếm giải thích tốt về cơ chế Ngoại lệ trong JS.Tôi làm cách nào để phân biệt các loại ngoại lệ khác nhau?

Dường như tương tự như C++, JS cho phép ném về mọi đối tượng, thay vì chỉ ném một đối tượng Ngoại lệ (có thể do tính chất động).

throw 'An error occured.'; 

công trình, cũng như

throw new Exception('An error occured.'); 

catchfinally cả dường như làm việc như Java tương đương của họ. Tuy nhiên, tôi không biết thực tiễn tốt nhất được chấp nhận rộng rãi về ngoại lệ là gì.

Vì vậy, ví dụ, là nó hợp pháp để ném các đối tượng kiểu chuỗi, như:

throw 'An error occured'; 

Làm thế nào tôi có thể phân biệt giữa các loại khác nhau của trường hợp ngoại lệ?

+0

Bạn sẽ phải thu hẹp câu hỏi của mình. Các phương pháp hay nhất về điều gì? –

Trả lời

12

Ném và bắt ngoại lệ là khá tốn kém, và với JavaScript, bạn chủ yếu sẽ nhận được ngoại lệ trong các trường hợp như khi bạn cố gắng phân tích chuỗi JSON bị định dạng sai. Tôi khuyên bạn nên tránh thử/nắm bắt càng nhiều càng tốt và thay vào đó tập trung vào việc kiểm tra lỗi theo cách thời trang cũ (kiểu trả về, đảm bảo các biến được khởi tạo đúng cách trước khi sử dụng chúng, v.v.) vì các ngoại lệ ít có khả năng xảy ra ở đây hơn trong C++ hoặc đặc biệt là Java hoặc .NET.

Andy E's recommendation là cách tốt nhất để thực sự xử lý chúng, nhưng nói chung, bạn nên cố gắng viết mã JavaScript bảo vệ để bạn thậm chí không cần thử/nắm bắt. Hãy nhớ rằng, ngay cả JavaScript JITed trong Chrome (động cơ nhanh nhất) vẫn chậm chạp so với Java hoặc C#, để không nói gì về C++, vì vậy bất kỳ thứ gì đắt tiền trong những ngôn ngữ đó có thể thậm chí còn nhiều hơn thế trong JavaScript.

+0

+1, nó đã không xảy ra với tôi để đề nghị chống lại try/catch báo cáo hoàn toàn, mặc dù tôi hiếm khi bao giờ cần phải viết một. Một trong những lý do bạn có thể cần thử/nắm bắt là khi xử lý các đối tượng lưu trữ (như 'ActiveXObjects' của IE) có thể không có hoặc không thể khởi tạo được. –

15

"Cách thực hành tốt nhất", tôi giả sử, là ném đúng loại đối tượng Lỗi liên quan đến sự cố gây ra ngoại lệ. ECMAScript định nghĩa một số loại đối tượng ngoại lệ, tất cả đều được kế thừa từ Error. Các đối tượng này là EvalError, RangeError, ReferenceError, TypeErrorURIError.

Những nhà xây dựng được sử dụng bởi các chức năng ECMAScript bản địa, cho phép bạn làm điều gì đó như thế này:

try { 
    // do something 
} 
catch (e) { 
    if (e instanceof TypeError) { 
     // do something else 
    } 
} 

Nói chung, sử dụng câu lệnh throw mà không sử dụng một đối tượng ngoại lệ đập vào mắt tôi thực hành như nghèo vì nhiều lý do, trong đó có :

  • Mã được thiết kế để xử lý ngoại lệ có thể được mong đợi là đối tượng Error, nhận nguyên thủy có thể dẫn đến các tác dụng phụ không mong muốn hoặc không thể xử lý ngoại lệ mà không sửa đổi mã xử lý. Ví dụ về điều này là thiếu thuộc tính stack trên kết quả từ biểu thức ném.
  • Khi không được sử dụng trong câu lệnh try/catch, Explorers Internet 8 trở xuống sẽ ném một ngoại lệ khác về nỗ lực của bạn để ném, với thông báo, "Ngoại lệ được ném và không bị bắt"*. Điều này thậm chí còn khó hiểu hơn nếu bạn đang gỡ lỗi bằng cách sử dụng các công cụ dành cho nhà phát triển hoặc có trình xử lý ngoại lệ chung được đặt thành window.onerror.

Vì vậy, có, nói chung dính vào trường hợp ném đúng Error hoặc các đối tượng kế thừa của nó.

* nb, IE cũng thực hiện việc này đối với các loại đối tượng Lỗi không được xây dựng trực tiếp từ Error. Có, tôi biết đó là ngu ngốc, nhưng họ đã sửa nó trong IE 9 mặc dù họ nói với tôi rằng đó là "theo thiết kế".

+6

'throw ' là một mẫu chống chỉ đơn thuần vì lý do lỗi trả về trong 'catch' không có thuộc tính' .stack' nếu nó không phải là một thực thể 'Lỗi' thực và đó là RAGE thuần túy. Là một sang một bên, try/catch/throw là một mô hình chống hiệu suất chung trong JS và nên tránh nếu có thể. – Raynos

2

Nếu bạn đang xây dựng một ứng dụng AJAX - ngoại lệ có thể không hữu ích.Do tính chất không đồng bộ của hoạt động ajax, xử lý lỗi sẽ không làm việc như bạn có thể mong đợi

function save_data(){ 
    try { 
     ajax(some_ulr, function(){ 
      //callback 
      do_wrong_thing(); 
     }); 
    } catch(e){ 
     handler_error(); 
    } 
} 

trong đoạn mã trên, lỗi do do_wrong_thing sẽ không kích hoạt phần bắt.

+2

Mã async cũng phá vỡ 'return' mặc dù vậy nên được mong đợi ... – hugomg

Các vấn đề liên quan