web-dev-qa-db-fra.com

Comment vérifier "indéfini" en JavaScript?

Quel est le moyen le plus approprié de tester si une variable est indéfinie en JavaScript? J'ai vu plusieurs manières possibles:

if (window.myVariable)

Ou

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

Ou

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

Si vous souhaitez savoir si une variable a été déclarée quelle que soit sa valeur, utilisez l'opérateur in est le moyen le plus sûr. Considérez cet exemple.

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

Mais il se peut que ce ne soit pas le résultat escompté dans certains cas, car la variable ou la propriété a été déclarée mais tout simplement pas initialisée. Utilisez l'opérateur in pour une vérification 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 si elle a la valeur undefined, utilisez l'opérateur typeof.

if (typeof myVar !== 'undefined')

L'opérateur typeof est garanti pour renvoyer une chaîne. Les comparaisons directes avec undefined sont gênantes, car undefined peut être écrasé.

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

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

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

 false 
 0 
 "" 
 NaN 
 null 
 undefined 

Merci à @CMS d’avoir fait remarquer que votre troisième cas - if (myVariable) peut également générer une erreur dans deux cas. La première est quand la variable n'a pas été définie, ce qui jette un ReferenceError.

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

L'autre cas se présente lorsque la variable a été définie mais que sa fonction getter génère 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?
}
2484
Anurag

J'utilise personnellement

myVar === undefined

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


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

Maintenant, certaines personnes vont avoir peur en lisant ceci, en criant: "Attendez! WAAITTT !!! undefined peut être redéfini!"

Cool. Je sais ça. Là encore, la plupart des variables en Javascript peuvent être redéfinies. Ne devriez-vous jamais utiliser d'identifiant intégré pouvant être redéfini?

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

Le fait est que, pour effectuer beaucoup de travail réel dans JS, les développeurs doivent s’appuyer sur des identifiants redéfinissables 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 de brut === undefined est faux.

(Si vous êtes toujours effrayé par la redéfinition de undefined, pourquoi intégrez-vous aveuglément du code de bibliothèque non testé dans votre base de code? Ou encore plus simple: un outil de linting.)


En outre, comme avec l'approche typeof, cette technique peut "détecter" les variables non déclarées:

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

Mais ces deux techniques fuient dans leur abstraction. Je vous exhorte à ne pas utiliser ceci 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 in. (Dans de nombreux cas, vous pouvez simplement lire le code O_o).

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

Mais attendez! Il y a plus! Et si un prototype de chaîne magique se produisait…? Maintenant, même l'opérateur supérieur in ne suffit pas. (OK, j’en ai assez de cette partie, sauf que je dis que pendant 99% des cas, === undefined (et **** toux **** typeof) fonctionne très bien. Si vous vraiment attention, vous pouvez lire sur ce sujet tout seul.)

1045
Thomas Eding

Utiliser typeof est ma préférence. Cela fonctionnera lorsque la variable n'aura jamais été déclarée, contrairement à toute comparaison avec les opérateurs == ou === ou à la contrainte de type utilisant if. (undefined, contrairement à null, peut également être redéfini dans les environnements ECMAScript 3, ce qui le rend peu fiable pour la comparaison, bien que presque tous les environnements courants soient désormais conformes à ECMAScript 5 ou supérieur).

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

if (someUndeclaredVariable === undefined) { 
    // Throws an error
}
175
Tim Down

Vous devez utiliser typeof.

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

Mise à jour 2018-07-25

Cela fait presque cinq ans que ce billet a été publié, et JavaScript a parcouru un long chemin. En répétant les tests du message d'origine, je n'ai trouvé aucune différence cohérente entre les méthodes de test suivantes:

  • abc === undefined
  • abc === void 0
  • typeof abc == 'undefined'
  • typeof abc === 'undefined'

Même lorsque j'ai modifié les tests pour empêcher Chrome de les optimiser, les différences étaient insignifiantes. En tant que tel, je recommanderais maintenant abc === undefined pour plus de clarté.

Contenu pertinent de chrome://version:

  • Google Chrome: 67.0.3396.99 (version officielle) (64 bits) (cohorte: stable)
  • Révision: a337fbf3c2ab8ebc6b64b0bfcece73a20e2e2252b-refs/branch-heads/3396 @ {# 790}
  • OS: Windows
  • JavaScript: V8 6.7.288.46
  • Agent utilisateur: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, comme Gecko) Chrome/67.0.3396.99 Safari/537.36

Original post 2013-11-01

Dans Google Chrome, les opérations suivantes étaient légèrement plus rapides qu'un test typeof:

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

La différence était négligeable. Toutefois, ce code est plus concis et clair pour ceux qui savent ce que void 0 signifie. Notez cependant que abcdoit toujours être déclaré.

typeof et void étaient nettement plus rapides que la comparaison directe avec undefined. J'ai utilisé le format de test suivant dans la console de développeur 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 sont 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.

40
Zenexer

S'il n'est pas défini, il ne sera pas égal à une chaîne contenant les caractères "indéfini", car la chaîne n'est pas indéfinie.

Vous pouvez vérifier le type de la 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 à false lorsqu'elle est définie (par exemple, s'il s'agit d'une fonction), vous pouvez simplement évaluer la variable. Exemple:

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

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

17
Mathias Bynens

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

(Notez que l'utilisation de var pour les tests in fait une différence dans un wrapper avec une portée.)

Code pour 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 les 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
17
drzaus

Dans cet article je lis que les frameworks tels que nderscore.js utilisent cette fonction:

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

Personnellement, j'utilise toujours les éléments suivants:

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

La propriété window.undefined n'est pas accessible en écriture pour tous les navigateurs modernes (JavaScript 1.8.5 ou version ultérieure). 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 que il ne génère pas d'erreur si la variable n'a pas été définie.

Je préfère avoir l'approche d'utiliser

x === undefined 

parce qu’il échoue et explose au visage plutôt que de passer/échouer silencieusement si x n’a pas été déclaré auparavant. Cela me prévient que x n'est pas déclaré. Je crois que toutes les variables utilisées dans JavaScript doivent être déclarées.

12
Hrishi

Le moyen le plus fiable que je connaisse de vérifier undefined consiste à utiliser void 0.

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

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

Comme aucune des autres réponses ne 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
}
4
anmarti
// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
   // These statements execute.
}

if (x === undefined) { // Throws a ReferenceError

}
4
sourcecode
    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 
3
Gaurav

Au contraire de @Thomas Eding, répondez:

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

Prenons un exemple réel:

J'ai un nom de variable, mais je ne suis pas sûr qu'il soit 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.");
3
Vikas

Je l'utilise comme paramètre de fonction et l'exclue lors de l'exécution de la fonction, ce qui me permet d'obtenir le "vrai" indéfini. Bien que cela vous oblige à 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 pouvez utiliser typeof bien que. Mais tout mon code est généralement dans une fonction contenant de toute façon, donc utiliser cette méthode me permet probablement de gagner quelques octets ici et là.

0
Cristian Sanchez