Comment vérifier "undefined" en JavaScript?

Quelle est la façon la plus appropriée de tester si une variable n'est pas définie en JavaScript? J'ai vu plusieurs façons possibles:

if (window.myVariable) 

Ou

 if (typeof(myVariable) != "undefined") 

Ou

 if (myVariable) //This throws an error if undefined. Should this be in Try/Catch? 

Si vous êtes intéressé à savoir si une variable a été déclarée indépendamment de sa valeur, l'utilisation de l'opérateur est le moyen le plus sécurisé. Considérez cet exemple.

 // global scope var theFu; // theFu has been declared, but its value is undefined typeof theFu; // "undefined" 

Mais ce n'est peut-être pas le résultat souhaité pour certains cas, puisque la variable ou la propriété a été déclarée, mais simplement pas initialisée. Utilisez l'opérateur en pour un contrôle plus robuste.

 "theFu" in window; // true "theFoo" in window; // false 

Si vous souhaitez savoir si la variable n'a pas été déclarée ou a la valeur undefined , utilisez l'opérateur typeof .

 if (typeof myVar != 'undefined') 

Le typeof opérateur est garanti pour renvoyer une chaîne. Les comparaisons directes contre undefined sont gênantes car l' undefined peut être écrasée.

 window.undefined = "omg"; "omg" == undefined // true 

Comme l'a souligné @CMS, cela a été corrigé dans ECMAScript 5th ed., Et undefined n'est pas accessible en écriture.

if (window.myVar) inclura également ces valeurs fausses, donc ce n'est pas très robuste:

 faux
 0
 ""
 NaN
 nul
 indéfini

Merci à @CMS de souligner que votre troisième cas – if (myVariable) peut également lancer une erreur dans deux cas. Le premier est quand la variable n'a pas été définie qui jette un ReferenceError .

 // abc was never declared. if (abc) { // ReferenceError: abc is not defined } 

L'autre cas est lorsque la variable a été définie, mais a une fonction getter qui lance une erreur lorsqu'elle est invoquée. Par exemple,

 // or it's a property that can throw an error Object.defineProperty(window, "myVariable", { get: function() { throw new Error("W00t?"); }, set: undefined }); if (myVariable) { // Error: W00t? } 

J'utilise personnellement

 myVar === undefined 

Avertissement: Notez que === est utilisé sur == et que myVar a déjà été déclaré (non défini ).


Je n'aime pas typeof myVar === "undefined" . Je pense que c'est long et inutile. (Je peux faire la même chose en moins de code.)

Maintenant, certaines personnes vont se doucher quand elles lisent ceci, en criant: "Attendez! WAAITTT !!! undefined peut être redéfini!"

Cool. Je sais ça. Ensuite, la plupart des variables en Javascript peuvent être redéfinies. Ne devriez-vous jamais utiliser un identifiant intégré qui peut être redéfini?

Si vous suivez cette règle, bon pour vous: vous n'êtes pas un hypocrite.

La chose est, afin de faire beaucoup de travail réel dans JS, les développeurs doivent compter sur des identificateurs redéfinis pour être ce qu'ils sont. Je n'entends pas les gens me dire que je ne devrais pas utiliser setTimeout parce que quelqu'un peut

 window.setTimeout = function () { alert("Got you now!"); }; 

En bout de ligne, l'argument "il peut être redéfini" pour ne pas utiliser un raw === undefined est faux.

(Si vous avez encore peur d'être redéfinies, pourquoi intégrer aveuglément le code de bibliothèque non testé dans votre base de code? Ou même plus simple: un outil de lintage.)


De même, comme l'approche typeof , cette technique peut "détecter" les variables non déclarées:

 if (window.someVar === undefined) { doSomething(); } 

Mais ces deux techniques ont une fuite dans leur abstraction. Je vous exhorte à ne pas utiliser cela ou même

 if (typeof myVar !== "undefined") { doSomething(); } 

Considérer:

 var iAmUndefined; 

Pour déterminer si cette variable est déclarée ou non, vous devrez peut-être recourir à l'opérateur. (Dans de nombreux cas, vous pouvez simplement lire le code O_o).

 if ("myVar" in window) { doSomething(); } 

Mais attendez! Il y a plus! Que se passe-t-il si une magie de chaîne de prototypes se produit …? Maintenant, même le supérieur in opérateur ne suffit pas. (D'accord, j'ai terminé ici à propos de cette partie, sauf pour dire que pour 99% du temps, === undefined (et **** **** de la toux **** du typeof ) fonctionne très bien. Si vous vous inquiétez vraiment, vous pouvez Lire sur ce sujet seul).

L'utilisation de typeof est ma préférence. Il fonctionnera lorsque la variable n'a jamais été déclarée, contrairement à toute comparaison avec les opérateurs == ou === ou la contrainte de type en utilisant if . ( undefined , contrairement à null , peut également être redéfini dans les environnements ECMAScript 3, ce qui rend peu fiable pour la comparaison, bien que presque tous les environnements communs soient maintenant conformes à ECMAScript 5 ou plus).

 if (typeof someUndeclaredVariable == "undefined") { // Works } if (someUndeclaredVariable === undefined) { // Throws an error } 

Vous devez utiliser typeof .

 if (typeof something != "undefined") { // ... } 

Si elle n'est pas définie, elle ne sera pas égale à une chaîne contenant les caractères "indéfinis", car la chaîne n'est pas définie.

Vous pouvez vérifier le type de variable:

 if (typeof(something) != "undefined") ... 

Parfois, vous n'avez même pas à vérifier le type. Si la valeur de la variable ne peut pas être évaluée à fausse lorsqu'elle est définie (par exemple si elle est une fonction), vous pouvez simplement évaluer la variable. Exemple:

 if (something) { something(param); } 
 if (typeof foo == 'undefined') { // Do something }; 

Notez qu'une comparaison stricte ( !== ) n'est pas nécessaire dans ce cas, puisque typeof toujours une chaîne.

Quelques scénarios illustrant les résultats des différentes réponses: http://jsfiddle.net/drzaus/UVjM4/

(Notez que l'utilisation de var pour in tests fait une différence lorsque dans une enveloppe scopée)

Code de référence:

 (function(undefined) { var definedButNotInitialized; definedAndInitialized = 3; someObject = { firstProp: "1" , secondProp: false // , undefinedProp not defined } // var notDefined; var tests = [ 'definedButNotInitialized in window', 'definedAndInitialized in window', 'someObject.firstProp in window', 'someObject.secondProp in window', 'someObject.undefinedProp in window', 'notDefined in window', '"definedButNotInitialized" in window', '"definedAndInitialized" in window', '"someObject.firstProp" in window', '"someObject.secondProp" in window', '"someObject.undefinedProp" in window', '"notDefined" in window', 'typeof definedButNotInitialized == "undefined"', 'typeof definedButNotInitialized === typeof undefined', 'definedButNotInitialized === undefined', '! definedButNotInitialized', '!! definedButNotInitialized', 'typeof definedAndInitialized == "undefined"', 'typeof definedAndInitialized === typeof undefined', 'definedAndInitialized === undefined', '! definedAndInitialized', '!! definedAndInitialized', 'typeof someObject.firstProp == "undefined"', 'typeof someObject.firstProp === typeof undefined', 'someObject.firstProp === undefined', '! someObject.firstProp', '!! someObject.firstProp', 'typeof someObject.secondProp == "undefined"', 'typeof someObject.secondProp === typeof undefined', 'someObject.secondProp === undefined', '! someObject.secondProp', '!! someObject.secondProp', 'typeof someObject.undefinedProp == "undefined"', 'typeof someObject.undefinedProp === typeof undefined', 'someObject.undefinedProp === undefined', '! someObject.undefinedProp', '!! someObject.undefinedProp', 'typeof notDefined == "undefined"', 'typeof notDefined === typeof undefined', 'notDefined === undefined', '! notDefined', '!! notDefined' ]; var output = document.getElementById('results'); var result = ''; for(var t in tests) { if( !tests.hasOwnProperty(t) ) continue; // bleh try { result = eval(tests[t]); } catch(ex) { result = 'Exception--' + ex; } console.log(tests[t], result); output.innerHTML += "\n" + tests[t] + ": " + result; } })(); 

Et résultats:

 definedButNotInitialized in window: true definedAndInitialized in window: false someObject.firstProp in window: false someObject.secondProp in window: false someObject.undefinedProp in window: true notDefined in window: Exception--ReferenceError: notDefined is not defined "definedButNotInitialized" in window: false "definedAndInitialized" in window: true "someObject.firstProp" in window: false "someObject.secondProp" in window: false "someObject.undefinedProp" in window: false "notDefined" in window: false typeof definedButNotInitialized == "undefined": true typeof definedButNotInitialized === typeof undefined: true definedButNotInitialized === undefined: true ! definedButNotInitialized: true !! definedButNotInitialized: false typeof definedAndInitialized == "undefined": false typeof definedAndInitialized === typeof undefined: false definedAndInitialized === undefined: false ! definedAndInitialized: false !! definedAndInitialized: true typeof someObject.firstProp == "undefined": false typeof someObject.firstProp === typeof undefined: false someObject.firstProp === undefined: false ! someObject.firstProp: false !! someObject.firstProp: true typeof someObject.secondProp == "undefined": false typeof someObject.secondProp === typeof undefined: false someObject.secondProp === undefined: false ! someObject.secondProp: true !! someObject.secondProp: false typeof someObject.undefinedProp == "undefined": true typeof someObject.undefinedProp === typeof undefined: true someObject.undefinedProp === undefined: true ! someObject.undefinedProp: true !! someObject.undefinedProp: false typeof notDefined == "undefined": true typeof notDefined === typeof undefined: true notDefined === undefined: Exception--ReferenceError: notDefined is not defined ! notDefined: Exception--ReferenceError: notDefined is not defined !! notDefined: Exception--ReferenceError: notDefined is not defined 

Dans cet article, j'ai lu ces cadres comme Underscore.js utilisent cette fonction:

 function isUndefined(obj){ return obj === void 0; } 

Personnellement, j'utilise toujours ce qui suit:

 var x; if( x === undefined) { //Do something here } else { //Do something else here } 

La propriété window.undefined n'est pas accessible à l'écriture dans tous les navigateurs modernes (JavaScript 1.8.5 ou version ultérieure). À partir de la documentation de Mozilla: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined , je vois ceci: Une des raisons d'utiliser typeof () est qu'il ne lance pas d'erreur si La variable n'a pas été définie.

Je préfère avoir l'approche de l'utilisation

 x === undefined 

Car il échoue et me fait exploser dans mon visage plutôt que de passer / échouer silencieusement si x n'a pas été déclaré auparavant. Cela m'indique que x n'est pas déclaré. Je crois que toutes les variables utilisées dans JavaScript devraient être déclarées.

La façon la plus fiable dont je sais vérifier la undefinedundefined est d'utiliser void 0 .

Ceci est compatible avec les navigateurs plus récents et plus anciens, et ne peut pas être écrasé comme window.undefined peut dans certains cas.

 if( myVar === void 0){ //yup it's undefined } 

Dans Google Chrome, ce qui suit a été légèrement plus rapide qu'un typeof test:

 if (abc === void 0) { // Undefined } 

La différence était négligeable. Cependant, ce code est plus concis et plus clair en un coup d'œil à quelqu'un qui sait ce qu'est le void 0 . Notez cependant que abc doit toujours être déclaré.

Les typeof et les void étaient significativement plus rapides que la comparaison directe contre undefined . J'ai utilisé le format de test suivant dans la console de développement Chrome:

 var abc; start = +new Date(); for (var i = 0; i < 10000000; i++) { if (TEST) { void 1; } } end = +new Date(); end - start; 

Les résultats étaient les suivants:

 Test: | abc === undefined abc === void 0 typeof abc == 'undefined' ------+--------------------------------------------------------------------- x10M | 13678 ms 9854 ms 9888 ms x1 | 1367.8 ns 985.4 ns 988.8 ns 

Notez que la première ligne est en milli secondes, tandis que la deuxième ligne est en nano secondes. Une différence de 3,4 nanosecondes n'est rien. Les temps étaient assez cohérents dans les tests ultérieurs.

Comme aucune des autres réponses m'a aidé, je suggère de le faire. Cela a fonctionné pour moi dans Internet Explorer 8:

 if (typeof variable_name.value === 'undefined') { // variable_name is undefined } 
 // x has not been defined before if (typeof x === 'undefined') { // Evaluates to true without errors. // These statements execute. } if (x === undefined) { // Throws a ReferenceError } 

Au contraire de @Thomas Eding répondre:

Si j'oublie de déclarer myVar dans mon code, je vais recevoir myVar is not defined .

Prenons un véritable exemple:

J'ai un nom de variable, mais je ne sais pas s'il est déclaré quelque part ou non.

Alors la réponse de @Anurag aidera:

 var myVariableToCheck = 'myVar'; if (window[myVariableToCheck] === undefined) console.log("Not declared or declared, but undefined."); // Or you can check it directly if (window['myVar'] === undefined) console.log("Not declared or declared, but undefined."); 
  var x; if (x === undefined) { alert ("I am declared, but not defined.") }; if (typeof y === "undefined") { alert ("I am not even declared.") }; /* One more thing to understand: typeof ==='undefined' also checks for if a variable is declared, but no value is assigned. In other words, the variable is declared, but not defined. */ // Will repeat above logic of x for typeof === 'undefined' if (x === undefined) { alert ("I am declared, but not defined.") }; /* So typeof === 'undefined' works for both, but x === undefined only works for a variable which is at least declared. */ /* Say if I try using typeof === undefined (not in quotes) for a variable which is not even declared, we will get run a time error. */ if (z === undefined) { alert ("I am neither declared nor defined.") }; // I got this error for z ReferenceError: z is not defined 

Je l'utilise comme paramètre de fonction et je l'exclue sur l'exécution de la fonction, de sorte que j'obtiens le "réel" indéfini. Bien qu'il vous soit nécessaire de mettre votre code dans une fonction. J'ai trouvé cela en lisant la source jQuery.

 undefined = 2; (function (undefined) { console.log(undefined); // prints out undefined // and for comparison: if (undeclaredvar === undefined) console.log("it works!") })() 

Bien sûr, vous pourriez simplement utiliser le typeof . Mais tout mon code est généralement dans une fonction contenant de toute façon, donc l'utilisation de cette méthode permet probablement d'économiser quelques octets ici et là.