2012-01-24 13 views
14

Sto iniziando a imparare JavaScript, finora nessun problema, ma ho difficoltà a trovare una buona spiegazione del meccanismo di eccezione in JS.Come faccio a distinguere tra diversi tipi di eccezioni?

Sembra simile a C++, JS consente di lanciare su ogni oggetto, invece di lanciare un oggetto Exception (probabilmente a causa della sua natura dinamica).

throw 'An error occured.'; 

opere, così come

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

catch e finally entrambi sembrano funzionare come il loro equivalente Java. Tuttavia, non so quali sono le migliori pratiche ampiamente accettate in merito alle eccezioni.

Così, per esempio, è legittimo per gettare oggetti di tipo stringa, come:

throw 'An error occured'; 

Come dovrei distinguere tra diversi tipi di eccezioni?

+0

Dovrai restringere la tua domanda. Migliori pratiche in termini di cosa? –

risposta

12

L'eccezione per lanciare e catturare è piuttosto costosa e, con JavaScript, si ottengono principalmente eccezioni in casi come quando si tenta di analizzare una stringa JSON malformata. Ti suggerisco di evitare try/catch il più possibile e invece di concentrarti sul controllo degli errori nel vecchio modo (tipi restituiti, assicurandoti che le variabili siano correttamente inizializzate prima di utilizzarle, ecc.) Poiché le eccezioni sono meno probabili qui che in C++ o soprattutto Java o .NET.

Andy E's recommendation è una buona soluzione per gestirli effettivamente, ma in generale, dovresti provare a scrivere il codice JavaScript in modo difensivo in modo da non aver nemmeno bisogno di try/catch. Ricorda, anche JavaScript JITed in Chrome (motore più veloce) è ancora lento come diamine rispetto a Java o C#, per non parlare di C++, quindi tutto ciò che è costoso in quei linguaggi è probabile che lo sia ancora di più in JavaScript.

+0

+1, non mi è venuto in mente di raccomandare contro le dichiarazioni try/catch del tutto, anche se raramente ho mai bisogno di scriverne uno. Uno dei motivi per cui potresti aver bisogno di un try/catch è quando si ha a che fare con oggetti host (come 'ActiveXObjects' di IE) che potrebbero non essere presenti o non essere in grado di essere istanziati. –

15

La "best practice", suppongo, consiste nel lanciare il tipo corretto di oggetto Error relativo al problema che causa l'eccezione. ECMAScript definisce diversi tipi di oggetti di eccezione, tutti ereditati da Error. Questi oggetti sono EvalError, RangeError, ReferenceError, TypeError e URIError.

Quei costruttori sono utilizzati da funzioni ECMAScript native, che consente di fare qualcosa di simile:

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

In generale, utilizzando l'istruzione throw senza l'utilizzo di un oggetto eccezione mi sembra pratica come poveri per diversi motivi, tra cui :

  • codice progettato per gestire le eccezioni possono essere in attesa di un oggetto Error, ricevendo un primitivo può provocare effetti collaterali imprevisti o l'incapacità di gestire l'eccezione senza modificare il codice di gestione. Un esempio di ciò è la mancanza di una proprietà stack sul risultato dell'espressione throw.
  • Quando non è utilizzato in un try/catch, Internet Explorers 8 e minore sarà un'eccezione diversa sul tentativo di lanciare, con il messaggio, "eccezione generata e non catturato"*. Ciò può essere ancora più confuso se si esegue il debug utilizzando gli strumenti per sviluppatori o se un gestore di eccezioni globale è impostato su window.onerror.

Quindi, sì, in generale attenersi alle istanze di lancio appropriate Error o ai relativi oggetti ereditari.

* nb, IE lo fa anche per i tipi di oggetto Errore che non sono costruiti direttamente da Error. Sì, lo so che è stupido, ma lo hanno risolto in IE 9 anche se mi hanno detto che era "di progettazione".

+6

'throw ' è un pattern anti solo per il fatto che l'errore restituito in 'catch' non ha una proprietà' .stack' se non è una vera istanza di 'Error' e quella è pura RAGE. Per inciso, try/catch/throw è un pattern anti performance generale in JS e dovrebbe essere evitato laddove possibile. – Raynos

2

Se si sta creando un'app AJAX, le eccezioni potrebbero non essere così utili.A causa della natura asincrona di operazioni Ajax, la gestione degli errori non funzionerà come ci si potrebbe aspettare

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

nel frammento di codice di cui sopra, l'errore causato dalla do_wrong_thing sezione cattura non si innescherà.

+2

Il codice asincrono rompe anche 'return' anche se in modo tale che dovrebbe essere previsto ... – hugomg

Problemi correlati