Les mots précédents
La gestion des erreurs est cruciale pour le développement d'applications Web. Il ne peut pas prédire les erreurs possibles à l'avance et les stratégies de récupération ne peuvent pas être adoptées à l'avance, ce qui peut conduire à une mauvaise expérience utilisateur. Étant donné que toute erreur JavaScript peut rendre la page Web inutilisable, en tant que développeur, vous devez savoir quand, pourquoi et ce qui se passera. Cet article présentera en détail le mécanisme de gestion des erreurs en JavaScript en détail
objet d'erreur
L'objet d'erreur est un objet contenant des informations d'erreur et est un objet natif de JavaScript. Lorsqu'une erreur se produit pendant l'analyse du code ou l'exécution, le moteur JavaScript générera automatiquement et lancera une instance de l'objet d'erreur, puis le programme entier sera interrompu là où l'erreur se produit.
Console.log (t); // UNCAPER REFEREELERROR: T n'est pas défini
ECMA-262 Spécifie qu'un objet d'erreur comprend deux propriétés: message et nom. L'attribut de message enregistre le message d'erreur, tandis que l'attribut de nom enregistre le type d'erreur
La copie de code est la suivante:
// Généralement, utilisez l'instruction TRY-Catch pour assister aux erreurs
essayer{
T;
} catch (ex) {
console.log (ex.Message); // t n'est pas défini
console.log (ex.name); // ReferenceError
}
Le navigateur a également élargi les propriétés de l'objet d'erreur et ajouté d'autres informations pertinentes. Parmi eux, le plus mis en œuvre par les fabricants de navigateurs est l'attribut de pile, qui indique des informations sur la trace de pile (Safari ne le prend pas en charge)
La copie de code est la suivante:
essayer{
T;
} catch (ex) {
console.log (ex.stack); // @ fichier: /// d: /wamp/www/form.html: 12: 2
}
Bien sûr, vous pouvez utiliser le constructeur Error () pour créer un objet d'erreur. Si le paramètre de message est spécifié, l'objet d'erreur l'utilisera comme propriété de message; S'il n'est pas spécifié, il utilisera une chaîne par défaut prédéfinie comme valeur de la propriété
La copie de code est la suivante:
Nouvelle erreur ();
Nouvelle erreur (message);
// Généralement, utilisez une déclaration de lancer pour lancer des erreurs
Jetez une nouvelle erreur («test»); // Erreur non revêtue: Tester
Jetez une nouvelle erreur (); // Erreur non approuvée
La copie de code est la suivante:
fonction userError (message) {
this.Message = message;
this.name = "userror";
}
UserError.prototype = new Error ();
Usererror.prototype.constructor = userError;
Jetez un nouvel utilisateur ("ErrorMessage"); // Usererror non cambré: ErrorMessage
Lorsque le constructeur Error () est appelé directement comme une fonction sans utiliser le nouvel opérateur, son comportement est le même que lorsque le nouvel opérateur est appelé
La copie de code est la suivante:
Erreur();
Erreur (message);
Erreur de lancer ('test'); // Erreur non cinglée: Tester
lancer une erreur (); // une erreur non cambrée
L'objet d'erreur a une méthode toString (), qui renvoie l'attribut de message de l'objet d'erreur.
La copie de code est la suivante:
var test = nouvelle erreur ('Testerror');
console.log (test.toString ()); // 'Erreur: Testerror'
Type d'erreur
Il existe de nombreux types d'erreurs qui peuvent se produire lors de l'exécution du code. Chaque erreur a un type d'erreur correspondant, et lorsqu'une erreur se produit, un objet d'erreur du type correspondant sera lancé. ECMA-262 définit les 7 types d'erreur suivants:
La copie de code est la suivante:
Erreur
EVALERROR (EMVER ERROR)
RangeError (RangeError)
ReferenceError (erreur de référence)
Syntaxerror (erreur de syntaxe)
TypeError (erreur de type)
Urierror (erreur URI)
Où l'erreur est le type de base et d'autres types d'erreur sont hérités de ce type. Par conséquent, tous les types d'erreur partagent un ensemble des mêmes propriétés. Les erreurs de type d'erreur sont rares, et s'il y en a, elles sont également lancées par le navigateur; Le but principal de ce type de base est que les développeurs lancent des erreurs personnalisées
【Evaluror (Evor Error)】
Lorsque la fonction EVAL n'est pas exécutée correctement, une erreur d'évaluror sera lancée. Ce type d'erreur n'apparaît plus dans ES5, mais continuera d'être préservé pour assurer la compatibilité avec les codes précédents.
【RangeError (RangeError)】
Une erreur du type de plage.
La copie de code est la suivante:
Nouveau tableau (-1); // UNCAPED RangeError: longueur de tableau non valide
Nouveau tableau (numéro.max_value); // non apporté RangeError: longueur de tableau non valide
(1234) .Toexponentiel (21); // non cambriol
(1234) .toexponentiel (-1); //// Unvried RangeError: L'argument ToExponential () doit être compris entre 0 et 20
【ReferenceError (erreur de référence)】
ReferenceError sera déclenché lors de la référence à une variable ou à une erreur de type LVALUE INNÉRIEURE.
a; // non cingtoraterror: a n'est pas défini
1 ++; // UNCAVER REFELERERROR: Expression non valide de la main gauche dans le fonctionnement du post-fixe
【Syntaxerror (syntaxerror)】
Lorsque les règles de syntaxe ne sont pas respectées, une syntaxerror sera lancée (erreur de syntaxe)
La copie de code est la suivante:
// Le nom de la variable est mauvais
var 1a; // Syntaxerror non cambré: numéro inattendu
// supports manquants
Console.log 'Hello'); // non apparenté Syntaxerror: chaîne inattendue
【TypeError (erreur de type)】
L'erreur de type EERROR sera causée lorsque les types inattendus sont stockés en variables ou lors de l'accès à des méthodes inexistantes. Bien que les causes des erreurs soient diverses, en fin de compte, c'est parce que le type de variable ne répond pas aux exigences lors de l'exécution d'un type de fonctionnement spécifique.
La copie de code est la suivante:
var o = new 10; // non apparenté TypeError: 10 n'est pas un constructeur
alert ('name' dans true); // non cambriol
Function.prototype.toString.call ('name'); // non apparenté TypeError: function.prototype.tostring n'est pas générique
【Urierror (erreur d'URI)】
Urierror est une erreur lancée lorsque les paramètres des fonctions liés à l'URI sont incorrects. Il implique principalement six fonctions: Encodeuri (), Decodeuri (), EncodeuriComponent (), DecodeuRIComponent (), Escape () et UnEscape ().
Decodeuri ('% 2'); // Urierror: URI malforme
Événement d'erreur
Toutes les erreurs qui ne sont pas traitées via TRY-PATCH déclencheront l'événement d'erreur de l'objet Window
L'événement d'erreur peut recevoir trois paramètres: message d'erreur, URL où se trouve l'erreur et le numéro de ligne. Dans la plupart des cas, seuls les messages d'erreur sont utiles car l'URL ne donne que l'emplacement du document, et le numéro de ligne fait référence à une ligne de code qui peut provenir du code JavaScript intégré ou d'un fichier externe.
Pour spécifier un gestionnaire d'événements d'erreur, vous pouvez utiliser la technologie de niveau DOM0 ou utiliser le format standard des événements de niveau DOM2
La copie de code est la suivante:
// Niveau Dom0
window.onerror = fonction (message, url, ligne) {
alerte (message);
}
// Niveau Dom2
window.addeventListener ("erreur", fonction (message, url, ligne) {
alerte (message);
});
La question de savoir si le navigateur affiche un message d'erreur standard dépend de la valeur de retour d'Onerror. Si la valeur de retour est fausse, un message d'erreur s'affiche dans la console; Si la valeur de retour est vraie, elle ne s'affiche pas
La copie de code est la suivante:
// Console affiche le message d'erreur
window.onerror = fonction (message, url, ligne) {
alerte (message);
retourne false;
}
un;
// La console n'affiche pas le message d'erreur
window.onerror = fonction (message, url, ligne) {
alerte (message);
Retour Vrai;
}
un;
Ce gestionnaire d'événements est la dernière ligne de défense pour éviter les erreurs de rapport de navigateur. Idéalement, vous ne devriez pas l'utiliser chaque fois que possible. Tant que vous pouvez utiliser l'instruction TRY-Catch de manière appropriée, il n'y aura pas d'erreurs transmises au navigateur et l'événement d'erreur ne sera pas déclenché.
L'image prend également en charge les événements d'erreur. Tant que l'URL dans la caractéristique SRC de l'image ne peut pas renvoyer le format d'image reconnu, un événement d'erreur sera déclenché. Pour le moment, l'événement d'erreur suit le format DOM et renvoie un objet d'événement ciblant l'image comme cible
Une boîte d'avertissement apparaît lorsque l'image est chargée. Lorsqu'un événement d'erreur se produit, le processus de téléchargement d'image est terminé, ce qui signifie qu'il ne peut plus être téléchargé.
La copie de code est la suivante:
var image = new image ();
image.src = 'Smilex.gif';
image.onerror = fonction (e) {
console.log (e);
}
lancer une déclaration et lancer une erreur
L'instruction Throw est utilisée pour lancer une erreur. Lorsqu'une erreur est lancée, vous devez spécifier une valeur à l'instruction Throw. Quel type est cette valeur? Il n'y a aucune exigence.
[Remarque] Le processus de lancer une erreur est bloqué et le code ultérieur ne sera pas exécuté
La copie de code est la suivante:
lancer 12345;
jeter «bonjour monde»;
jeter vrai;
Throw {name: 'javascript'};
Vous pouvez utiliser l'instruction Throw pour lancer manuellement un objet d'erreur
La copie de code est la suivante:
lancer une nouvelle erreur («quelque chose de mal s'est produit»);
Jetez une nouvelle syntaxerror («Je n'aime pas votre syntaxe»);
Jetez un nouveau typeError («quel type de variable m'emmenez-vous?»);
Jetez un nouveau RangeError («Désolé, vous n'avez pas la gamme.»);
lancer un nouvel évaluateur («qui n'évalue pas»);
Jetez un nouvel Urierror («Uri, c'est vous?»);
Jetez une nouvelle référence («vous ne citez pas correctement vos références»);
L'utilisation de chaînes prototypes peut également créer des types d'erreur personnalisés en héritant d'erreur (les chaînes prototypes sont introduites au chapitre 6). À ce stade, vous devez spécifier les attributs de nom et de message pour le type d'erreur nouvellement créé
Le navigateur traite les types d'erreur personnalisés hérités de l'erreur, tout comme les autres types d'erreur. La création d'une erreur personnalisée est utile si vous souhaitez attraper l'erreur que vous lancez et la traitez différemment de l'erreur du navigateur.
La copie de code est la suivante:
fonction CustomError (message) {
this.name = 'CustomError';
this.Message = message;
}
CustomError.prototype = new Error ();
lancer un nouveau CustomError («mon message»);
Lorsqu'une instruction Throw est rencontrée, le code cessera de s'exécuter immédiatement. Le code continuera d'exécuter uniquement si une instruction TRY-Catch capture la valeur lancée.
Une explication plus détaillée est: Lorsqu'une exception est lancée, l'interprète JavaScript arrêtera immédiatement la logique en cours d'exécution et sautera au gestionnaire d'exceptions à proximité. Le gestionnaire d'exceptions est écrit dans la clause Catch de l'instruction TRY-Catch. Si le bloc de code qui lance l'exception n'a pas de clause de capture associée, l'interprète vérifiera le bloc de code fermé de niveau supérieur pour voir s'il dispose d'un gestionnaire d'exceptions associé. Et ainsi de suite jusqu'à ce qu'un gestionnaire d'exceptions soit trouvé. Si la fonction qui lance l'exception ne gère pas son instruction TRY-PATCH, l'exception sera propagée vers le haut avec le code qui appelle la fonction. De cette façon, l'exception sera propagée vers le haut le long de la structure lexicale de la méthode JavaScript et de la pile d'appels. Si aucun gestionnaire d'exception n'est trouvé, JavaScript gère l'exception en tant qu'erreur de programme et le signalera à l'utilisateur
Essayez la déclaration de capture et l'erreur de capture
ECMA-262 Edition 3 présente l'instruction TRY-Catch comme un moyen standard de gérer les exceptions en JavaScript, utilisé pour attraper et gérer les erreurs
Parmi eux, la clause d'essai définit le bloc de code où se trouvent les exceptions qui doivent être traitées. La clause Catch suit la clause d'essai. Lorsqu'une exception se produit quelque part dans le bloc d'essai, la logique de code à l'intérieur de la capture est appelée. La clause Catch est suivie du bloc final, où le code de nettoyage est placé. Peu importe si une exception se produit dans le bloc d'essai, la logique à l'intérieur du bloc final sera toujours exécutée. Bien que Catch et enfin soient facultatifs, la clause Try nécessite au moins l'un des deux pour former une déclaration complète avec lui.
Tous les blocs d'essai / catch / enfin doivent être enfermés avec des accolades bouclées. Les accolades ici sont nécessaires. Même s'il n'y a qu'une seule déclaration dans la clause, les accolades bouclées ne peuvent pas être omises.
essayer{
// De manière générale, le code ici commencera du début à la fin sans aucun problème
// mais parfois une exception est lancée, soit directement lancée par l'instruction Throw ou indirectement en appelant une méthode
} catch (e) {
// Si et seulement si une exception est lancée par le bloc d'essai, le code ici sera exécuté
// Ici, vous pouvez obtenir une référence à l'objet d'erreur ou à d'autres valeurs lancées par la variable locale E
// Le bloc de code ici peut gérer cette exception pour une raison quelconque, ou ignorer cette exception, et peut également remémorer l'exception via l'instruction Throw
} enfin{
// Peu importe si l'instruction TRY lance une exception, la logique est enfin toujours exécutée. Les moyens de résilier le bloc de déclaration d'essai sont:
// 1. Terminez normalement, exécutez la dernière déclaration du bloc d'énoncé
// 2. Terminer par déclaration de pause, de poursuite ou de retour
// 3. Jetez une exception, l'exception est capturée par la clause de capture
// 4. Jetez une exception, l'exception n'est pas prise, continue de se propager vers le haut
}
Généralement, mettez tout le code qui peut lancer des erreurs dans le bloc de l'instruction TRY et mettez le code utilisé pour la gestion des erreurs dans le bloc de capture
Si un code dans l'erreur de bloc d'essai se produit, le processus d'exécution de code sera immédiatement sorti et le bloc de capture sera exécuté. À l'heure actuelle, le bloc Catch recevra un objet avec un message d'erreur. Les informations réelles contenues dans cet objet varieront d'un navigateur à l'autre, mais le commun est qu'il existe un attribut de message qui stocke le message d'erreur
[Remarque] Assurez-vous de nommer l'objet d'erreur. Si la vidange, une erreur de syntaxe sera signalée.
La copie de code est la suivante:
essayer{
Q;
} catch (erreur) {
alert (error.sessage); // q n'est pas défini
}
// Syntaxerror non cinglable: jeton inattendu)
essayer{
Q;
}attraper(){
alert (error.sessage);
}
Catch accepte un paramètre indiquant la valeur lancée par le bloc de code d'essai
La copie de code est la suivante:
fonction Throwit (exception) {
essayer {
lancer une exception;
} catch (e) {
console.log ('capturé:' + e);
}
}
Throwit (3); // capturé: 3
Throwit ('bonjour'); // attrapé: Bonjour
Throwit (nouvelle erreur («une erreur s'est produite»)); // capturé: Erreur: une erreur s'est produite
Une fois que le bloc de capture de capture a saisi l'erreur, le programme ne sera pas interrompu et continuera à s'exécuter en fonction du processus normal.
La copie de code est la suivante:
essayer{
lancer "erreur";
} catch (e) {
console.log (111);
}
console.log (222);
// 111
// 222
Afin d'attraper différents types d'erreurs, des déclarations de jugement peuvent être ajoutées au bloc de code de capture
La copie de code est la suivante:
essayer {
foo.bar ();
} catch (e) {
if (e instanceof evaluerror) {
console.log (e.name + ":" + e.Message);
} else if (e instanceof rangeError) {
console.log (e.name + ":" + e.Message);
}
// ...
}
Bien que la clause enfin soit facultative dans l'instruction TRY-Catch, une fois la clause enfin utilisée, son code sera exécuté quoi qu'il arrive. En d'autres termes, tout le code du bloc de l'instruction TRY est exécuté normalement et enfin les clauses seront exécutées; Si le bloc de l'instruction Catch est exécuté en raison d'une erreur, la clause enfin sera toujours exécutée. Tant que le code contient enfin des clauses, quel que soit le code contenu dans le bloc d'essai ou de capture - ou même l'instruction RETOUR, l'exécution de la clause enfin ne sera pas empêchée.
La copie de code est la suivante:
// L'erreur n'est pas capturée car il n'y a pas de bloc de déclaration de capture. Après avoir exécuté le bloc de code enfin, le programme sera interrompu là où l'erreur est lancée.
Fonction CleanSup () {
essayer {
Jetez une nouvelle erreur ('Error ...');
console.log («Cette ligne ne sera pas exécutée»);
} enfin {
Console.log («Terminer le travail de nettoyage»);
}
}
Nettoyage ();
// terminer les travaux de nettoyage
// Erreur: quelque chose s'est mal passé ...
La copie de code est la suivante:
fonction testFinnally () {
essayer{
retour 2;
} catch (erreur) {
retour 1;
} enfin{
retour 0;
}
}
testFinnally (); // 0
[Remarque] La valeur du nombre de l'instruction RETOUR est obtenue avant l'exécution du bloc de code final.
La copie de code est la suivante:
Var Count = 0;
fonction countUp () {
essayer {
Return Count;
} enfin {
Count ++;
}
}
countUp (); // 0
console.log (count); // 1
La copie de code est la suivante:
fonction f () {
essayer {
console.log (0);
lancer "bug";
} catch (e) {
console.log (1);
Retour Vrai; // Cette phrase aurait été retardée jusqu'à la fin du bloc de code enfin avant l'exécution
console.log (2); // ne fonctionnera pas
} enfin {
console.log (3);
retourne false; // Cette phrase couvrira le retour précédent
console.log (4); // ne fonctionnera pas
}
console.log (5); // ne fonctionnera pas
}
var result = f ();
// 0
// 1
// 3
console.log (résultat); // false
【Tips】 Portée au niveau du bloc
Une utilisation courante des instructions de capture essai consiste à créer des étendues au niveau du bloc où les variables déclarées ne sont valables que dans la capture
ES6 introduit le mot-clé LET pour créer une portée au niveau du bloc pour les variables qu'il déclare. Cependant, dans la situation actuelle de ES3 et ES5, les déclarations de couple de gamme sont souvent utilisées pour obtenir des effets similaires
À partir du code suivant, E n'existe que dans la clause Catch, et une erreur sera lancée lorsque vous essayez de la référencer à partir d'ailleurs.
La copie de code est la suivante:
essayer{
lancer une nouvelle erreur (); // en tête d'une erreur
} catch (e) {
console.log (e); // erreur (…)
}
console.log (e); // non cingtoraterror: e n'est pas défini
Erreurs communes
Le cœur de la gestion des erreurs est de savoir d'abord quelles erreurs se produiront dans le code. Étant donné que JavaScript est tapé de manière lâche et ne vérifie pas les paramètres de la fonction, l'erreur ne se produira que pendant le code. D'une manière générale, trois types d'erreurs doivent être prêts à prêter une attention: l'erreur de conversion de type, l'erreur de type de données et l'erreur de communication
【Erreur de conversion de type】
L'erreur de conversion de type se produit lors de l'utilisation d'un opérateur ou de l'utilisation d'une autre structure linguistique des types de données qui peuvent convertir automatiquement les valeurs.
L'instruction de contrôle de flux est sujette aux erreurs de conversion de type. Des instructions comme IF convertiront automatiquement n'importe quelle valeur en booléen avant de déterminer l'opération suivante. Surtout si les déclarations, si elles sont utilisées mal, elles sont les plus susceptibles de faire des erreurs.
Les variables nommées inutilisées se voient automatiquement attribuer des valeurs non définies. La valeur non définie peut être convertie en valeur booléenne false, donc l'instruction IF dans la fonction suivante ne s'applique en fait qu'aux cas où le troisième paramètre est fourni. Le problème est qu'il n'est pas seulement non défini pour être converti en false, et ce n'est pas seulement des valeurs de chaîne qui peuvent être converties en vrai. Par exemple, si le troisième paramètre est la valeur 0, le test de l'instruction if échouera et le test de la valeur logarithmique 1 passera
La copie de code est la suivante:
fonction concat (str1, str2, str3) {
Var Result = str1 + str2;
if (str3) {// pas absolument comme ça
Résultat + = str3;
}
Résultat de retour;
}
L'utilisation de valeurs non bolores dans les instructions de contrôle de flux est une source d'erreurs extrêmement courante. Pour éviter de telles erreurs, il est nécessaire de passer en valeurs booléennes lorsque les conditions sont comparées. En fait, effectuer une certaine forme de comparaison peut y parvenir
La copie de code est la suivante:
fonction concat (str1, str2, str3) {
Var Result = str1 + str2;
if (typeof str3 == 'string') {// plus approprié
Résultat + = str3;
}
Résultat de retour;
}
【Erreur de type de données】
JavaScript est typique vaguement et ne sera pas comparé pour s'assurer que leur type de données est correct jusqu'à ce que les variables et les paramètres de fonction soient utilisés. Afin de garantir que les erreurs de type de données ne se produisent pas, seul le code de détection de type de données approprié peut être écrit. Les erreurs de type de données sont les plus susceptibles de se produire lors du passage des valeurs inattendues pour tracer les fonctions
La copie de code est la suivante:
// Fonctions non sécurisées, toute valeur non-réseau provoquera des erreurs
fonction réversion (valeurs) {
if (valeurs) {
valeurs.sort ();
valeurs.reverse ();
}
}
Une autre erreur courante consiste à comparer les paramètres avec les valeurs nuls. La comparaison avec NULL garantit uniquement que les valeurs correspondantes ne sont pas nuls et non définies. Pour s'assurer que la valeur transmise est valide, il ne suffit pas de détecter uniquement les valeurs nulles
La copie de code est la suivante:
// Fonctions non sécurisées, toute valeur non-réseau provoquera des erreurs
fonction réversion (valeurs) {
if (valeurs! = null) {
valeurs.sort ();
valeurs.reverse ();
}
}
Si un objet contenant la méthode tri () (plutôt qu'un tableau) est passé, il passera la détection, mais une erreur peut se produire lors de l'appel de la fonction reverse ()
La copie de code est la suivante:
// Fonctions non sécurisées, toute valeur non-réseau provoquera des erreurs
fonction réversion (valeurs) {
if (typeof valeurs.sort == 'fonction') {
valeurs.sort ();
valeurs.reverse ();
}
}
Dans le cas où vous savez exactement quel type vous devez transmettre, il est préférable d'utiliser l'instance de détecter son type de données
La copie de code est la suivante:
// Les valeurs sûres et non-terrasse sont ignorées
fonction réversion (valeurs) {
if (valeurs instance du tableau) {
valeurs.sort ();
valeurs.reverse ();
}
}
【Erreur de communication】
Avec la montée en puissance de la programmation Ajax, il est devenu monnaie courante pour les applications Web pour charger dynamiquement des informations ou des fonctionnalités pendant leur cycle de vie. Cependant, toute communication entre JavaScript et le serveur peut provoquer une erreur
Le problème le plus courant est que les données ne sont pas codées à l'aide d'encodeuRIComponent () avant de l'envoyer au serveur
La copie de code est la suivante:
//erreur
http://www.yourdomain.com/?redir=http://www.sometherdomain.com?a=b&c=d
// Appeler EncodeuRIComponent () pour toutes les chaînes après 'redir =' peut résoudre ce problème
http://www.yourdomain.com/?redir=http:%3a%2f%2fwww.sometherdomain.com%3FA%3DB%26C%3DD