La conception du langage Javascript n’est pas assez rigoureuse, et des erreurs peuvent survenir à de nombreux endroits si vous n’y prêtez pas attention.
Par exemple, considérons la situation suivante.
Maintenant, nous devons déterminer si un objet global myObj existe. S'il n'existe pas, déclarez-le. L'algorithme décrit en langage naturel est le suivant :
Copiez le code comme suit :
if (monObj n'existe pas){
déclarer monObj ;
}
Vous pensez peut-être qu’écrire ce code est facile. Mais en réalité, les problèmes grammaticaux impliqués sont bien plus complexes qu’on l’imagine. Juriy Zaytsev a souligné qu'il existe plus de 50 façons de déterminer si un objet Javascript existe. Ce n'est que si vous êtes très clair sur les détails d'implémentation du langage Javascript que vous pourrez faire la différence entre eux.
La première façon d'écrire
Intuitivement, vous pourriez penser que vous pourriez écrire :
Copiez le code comme suit :
si (!monObj) {
monObj = { } ;
}
Cependant, lors de l'exécution de ce code, le navigateur générera directement une erreur ReferenceError, provoquant l'interruption de l'opération. Qu'est-ce qui ne va pas?
À propos, lorsque l'instruction if détermine si myObj est vide, la variable n'existe pas encore, donc une erreur est signalée. Modifiez-le comme suit et il fonctionnera correctement.
Copiez le code comme suit :
si (!monObj) {
var monObj = { };
}
Pourquoi n’y a-t-il aucune erreur après l’ajout d’une variable ? Se pourrait-il que dans ce cas, lorsque l'instruction if porte un jugement, myObj existe déjà ?
Pour répondre à cette question, vous devez savoir comment fonctionne l'interpréteur Javascript. Le langage Javascript est "analyser d'abord, exécuter plus tard". La déclaration de variable a déjà été terminée lors de l'analyse, donc le code ci-dessus est en fait équivalent à :
Copiez le code comme suit :
var monObj;
si (!monObj) {
var monObj = { };
}
Par conséquent, lorsque l'instruction if émet un jugement, myObj existe déjà, donc aucune erreur n'est signalée. Il s’agit de l’effet « histing de code » de la commande var. L'interpréteur Javascript "promeut" uniquement les variables définies par la commande var et ne fonctionne pas sur les variables directement affectées sans utiliser la commande var. C'est pourquoi une erreur sera signalée si var n'est pas ajouté.
La deuxième façon d'écrire
En plus de la commande var, il existe une autre réécriture qui peut également obtenir les bons résultats :
Copiez le code comme suit :
si (!window.myObj) {
monObj = { } ;
}
Window est l'objet de niveau supérieur de JavaScript et toutes les variables globales sont ses propriétés. Par conséquent, déterminer si myobj est vide équivaut à déterminer si l'objet window possède l'attribut myobj. Cela peut éviter les erreurs ReferenceError car myObj n'est pas défini. Cependant, du fait de la standardisation du code, il est préférable d'ajouter var à la deuxième ligne :
Copiez le code comme suit :
si (!window.myObj) {
var monObj = { };
}
Ou écrit comme ceci :
si (!window.myObj) {
window.myObj = { };
}
La troisième façon d'écrire
L'inconvénient de la méthode d'écriture ci-dessus est que dans certains environnements d'exécution (tels que V8, Rhino), window peut ne pas être un objet de niveau supérieur. Pensez donc à le réécrire comme suit :
Copiez le code comme suit :
si (!this.myObj) {
this.myObj = { } ;
}
Au niveau des variables globales, le mot-clé this pointe toujours vers la variable de niveau supérieur, elle peut donc être indépendante des différents environnements d'exécution.
La quatrième façon d'écrire
Cependant, la manière d'écrire ci-dessus est moins lisible, et le pointeur de celle-ci est variable et sujet aux erreurs, nous la réécrivons donc davantage :
Copiez le code comme suit :
var global = ceci ;
si (!global.myObj) {
global.myObj = { };
}
Il est beaucoup plus clair d'utiliser la variable personnalisée global pour représenter l'objet de niveau supérieur.
La cinquième façon d'écrire
Vous pouvez également utiliser l'opérateur typeof pour déterminer si myObj est défini.
Copiez le code comme suit :
if (typeof myObj == "indéfini") {
var monObj = { };
}
Il s'agit actuellement de la méthode la plus utilisée pour déterminer si un objet JavaScript existe.
La sixième façon d'écrire
Puisque la valeur de myObj est directement égale à undefined lorsqu'elle est définie mais non attribuée, la méthode d'écriture ci-dessus peut être simplifiée :
Copiez le code comme suit :
if (myObj == non défini) {
var monObj = { };
}
Il y a deux choses à noter ici. Premièrement, le mot-clé var dans la deuxième ligne ne peut pas manquer, sinon une ReferenceError se produira. Deuxièmement, undefined ne peut pas être ajouté avec des guillemets simples ou doubles, car le type de données undefined est comparé ici. pas "indéfini "Cette chaîne.
La septième façon d'écrire
La méthode d'écriture ci-dessus est toujours vraie dans le cas d'une "comparaison exacte" (===) :
Copiez le code comme suit :
if (myObj === non défini) {
var monObj = { };
}
La huitième façon d'écrire
Selon la conception du langage JavaScript, undefined == null, donc comparer si myObj est égal à null peut également obtenir le résultat correct :
Copiez le code comme suit :
si (monObj == null) {
var monObj = { };
}
Cependant, bien que les résultats soient corrects, d’un point de vue sémantique, cette méthode de jugement est erronée et doit être évitée. Parce que null fait référence à un objet vide auquel a été attribué une valeur null, c'est-à-dire que cet objet a réellement une valeur, tandis qu'undéfini fait référence à un objet qui n'existe pas ou auquel aucune valeur n'est attribuée. Par conséquent, seul « l'opérateur de comparaison » (==) peut être utilisé ici. Si l'« opérateur de comparaison exact » (===) est utilisé ici, une erreur se produira.
La neuvième façon d'écrire
Vous pouvez également utiliser l'opérateur in pour déterminer si myObj est un attribut de l'objet de niveau supérieur :
Copiez le code comme suit :
if (!('myObj' dans la fenêtre)) {
window.myObj = { };
}
La dixième façon d'écrire
Enfin, utilisez la méthode hasOwnProperty pour déterminer si myObj est une propriété de l'objet de niveau supérieur :
Copiez le code comme suit :
if (!this.hasOwnProperty('myObj')) {
this.myObj = { } ;
}
Résumer
1. Si vous déterminez uniquement si l'objet existe, il est recommandé d'utiliser la cinquième méthode d'écriture.
2. Si en plus de savoir si l'objet existe, vous devez également déterminer si l'objet a une valeur nulle, il est recommandé d'utiliser la première méthode d'écriture.
3. Sauf circonstances particulières, toutes les variables doivent être déclarées à l'aide de la commande var.
4. Afin d'être multiplateforme, il est recommandé d'éviter d'utiliser window pour représenter des objets de niveau supérieur.
5. En langage Javascript, null et indéfini se confondent facilement. Dans les cas où les deux peuvent être impliqués, il est recommandé d'utiliser l'opérateur "comparaison exacte" (===).