Question Détecter une propriété d'objet indéfinie


Quelle est la meilleure façon de vérifier si une propriété d'objet dans JavaScript n'est pas définie?


2430
2017-08-26 07:25


origine


Réponses:


Utilisation:

if (typeof something === "undefined") {
    alert("something is undefined");
}

Si une variable d'objet possède des propriétés, vous pouvez utiliser la même chose comme ceci:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}

Depuis ECMAScript 5, undefined ne peut pas être écrasé, donc my_obj === undefined travaillerait aussi, mais seulement si my_obj existe. Cela peut ou peut ne pas être désiré, car vous pouvez aussi bien utiliser null si vous avez besoin de cette sémantique (voir Quelle est la différence entre null et indéfini dans JavaScript?). Pour les propriétés de l'objet cependant, cela fonctionne indépendamment du fait que la propriété existe.


2316
2018-01-06 12:27



Je crois qu'il y a un certain nombre de réponses incorrectes à ce sujet. Contrairement à la croyance commune, "indéfini" est ne pas un mot clé en JavaScript et peut en fait avoir une valeur qui lui est assignée.

Corriger le code

La manière la plus robuste d'effectuer ce test est:

if (typeof myVar === "undefined")

Cela retournera toujours le résultat correct, et même gère la situation où myVar n'est pas déclaré.

Code dégénéré. NE PAS UTILISER.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Aditionellement, myVar === undefined provoquera une erreur dans la situation où myVar n'est pas déclaré.


803
2017-08-23 18:03



En JavaScript il y a nul et voici indéfini. Ils ont des significations différentes.

  • indéfini signifie que la valeur de la variable n'a pas été définie; on ne sait pas quelle est la valeur.
  • nul signifie que la valeur de la variable est définie et définie sur null (n'a pas de valeur).

Marijn Haverbeke déclare, dans son livre en ligne gratuit "JavaScript éloquent"(soulignement le mien):

Il existe également une valeur similaire, null, dont la signification est 'cette valeur est définie, mais elle n'a pas de valeur'. La différence de sens entre undefined et null est principalement académique, et généralement pas très intéressant. Dans les programmes pratiques, il est souvent nécessaire de vérifier si quelque chose a une valeur. Dans ces cas, l'expression something == undefined peut être utilisée car, même si elles ne sont pas exactement de la même valeur, null == undefined produira true.

Donc, je suppose que la meilleure façon de vérifier si quelque chose n'était pas défini serait:

if (something == undefined)

J'espère que cela t'aides!

Modifier: En réponse à votre modification, les propriétés de l'objet doivent fonctionner de la même manière.

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

alert(person.name); // "John"
alert(person.fakeVariable); // undefined

133
2017-08-26 07:36



En dépit d'être véhémentement recommandé par beaucoup d'autres réponses ici, typeof  est un mauvais choix. Il ne devrait jamais être utilisé pour vérifier si les variables ont la valeur undefined, parce qu'il agit comme un contrôle combiné de la valeur undefined et pour savoir si une variable existe. Dans la grande majorité des cas, vous savez quand une variable existe, et typeof introduira simplement le potentiel d'un échec silencieux si vous faites une faute de frappe dans le nom de la variable ou dans la chaîne littérale 'undefined'.

var snapshot = …;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;

if (typeof foo === 'undefned') {
    //                   ^
    // misspelled – this will never run, but it won’t throw an error!
}

Donc, sauf si vous faites la détection de caractéristique², où il y a incertitude quant à savoir si un nom donné sera dans la portée (comme vérifier typeof module !== 'undefined' comme une étape dans le code spécifique à un environnement CommonJS), typeof est un choix nuisible lorsqu'il est utilisé sur une variable, et la bonne option est de comparer directement la valeur:

var foo = …;

if (foo === undefined) {
    ⋮
}

Quelques idées fausses communes à ce sujet comprennent:

  • que lire une variable "non initialisée" (var foo) ou paramètre (function bar(foo) { … }, appelé comme bar()) échouera. Ce n'est tout simplement pas vrai - les variables sans initialisation explicite et les paramètres qui n'ont pas reçu de valeurs deviennent toujours undefined, et sont toujours dans la portée.

  • cette undefined peut être écrasé. Il y a beaucoup plus à ça. undefined n'est pas un mot clé en JavaScript. Au lieu de cela, il s'agit d'une propriété sur l'objet global avec la valeur Undefined. Cependant, depuis ES5, cette propriété a été lecture seulement et non-configurable. Aucun navigateur moderne ne permettra le undefined propriété à changer, et à partir de 2017, cela a été le cas depuis longtemps. Le manque de mode strict n'affecte pas undefinedLe comportement soit - il fait juste des déclarations comme undefined = 5 ne fais rien au lieu de lancer. Comme ce n'est pas un mot-clé, vous pouvez déclarer variables avec le nom undefined, et ces variables pourraient être changées, rendant ce modèle une fois commun:

    (function (undefined) {
        // …
    })()
    

    plus dangereux que d'utiliser le mondial undefined. Si vous devez être compatible ES3, remplacez undefined avec void 0 - ne pas recourir à typeof. (void a toujours été un opérateur unaire qui évalue à la valeur indéfinie pour n'importe quel opérande.)

Avec la façon dont les variables fonctionnent, il est temps d'aborder la vraie question: les propriétés de l'objet. Il n'y a aucune raison de jamais utiliser typeof pour les propriétés d'objet. L'exception précédente concernant la détection de caractéristiques ne s'applique pas ici - typeof a seulement un comportement spécial sur les variables, et les expressions qui référencent les propriétés de l'objet ne sont pas des variables.

Ce:

if (typeof foo.bar === 'undefined') {
    ⋮
}

est toujours exactement équivalent à ceci³:

if (foo.bar === undefined) {
    ⋮
}

et en tenant compte des conseils ci-dessus, pour éviter de dérouter les lecteurs quant à la raison pour laquelle vous utilisez typeof, parce que cela a le plus de sens d'utiliser === pour vérifier l'égalité, car il pourrait être refactorisé pour vérifier la valeur d'une variable plus tard, et parce que cela semble tout simplement mieux, vous devriez toujours utiliser === undefined³ ici aussi.

Quelque chose d'autre à considérer quand il s'agit de propriétés d'objet est de savoir si vous voulez vraiment vérifier pour undefined du tout. Un nom de propriété donné peut être absent sur un objet (produisant la valeur undefined quand lu), présente sur l'objet lui-même avec la valeur undefined, présent sur le prototype de l'objet avec la valeur undefined, ou présent sur l'un ou l'autre de ceux qui ont unundefined valeur. 'key' in obj vous dira si une clé est n'importe où sur la chaîne prototype d'un objet, et Object.prototype.hasOwnProperty.call(obj, 'key') vous dira si c'est directement sur l'objet. Je n'entrerai pas dans les détails de cette réponse sur les prototypes et l'utilisation d'objets comme des cartes à cordes, parce que c'est principalement destiné à contrer tous les mauvais conseils dans d'autres réponses indépendamment des interprétations possibles de la question originale. Lire sur prototypes d'objets sur MDN pour plus!

¹ choix inhabituel de l'exemple de nom de variable? c'est du vrai code mort de l'extension NoScript pour Firefox.
² ne supposez pas que le fait de ne pas savoir ce qui est dans le champ d'application est correct en général, cependant. vulnérabilité de bonus causée par abus de la portée dynamique: Projet Zéro 1225
³ supposant à nouveau un environnement ES5 + et undefined se réfère à la undefined propriété de l'objet global. remplacer void 0 autrement.


130
2018-02-26 21:17



Qu'est-ce que ça veut dire: "propriété d'objet indéfini"?

En fait, cela peut signifier deux choses très différentes! Premièrement, cela peut signifier la propriété qui n'a jamais été définie dans l'objet et, deuxièmement, cela peut signifier propriété qui a une valeur indéfinie. Regardons ce code:

var o = { a: undefined }

Est o.a indéfini? Oui! Sa valeur est indéfinie. Est o.b indéfini? Sûr! Il n'y a pas de propriété 'b' du tout! OK, voyez maintenant comment les différentes approches se comportent dans les deux situations:

typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

Nous pouvons voir clairement que typeof obj.prop == 'undefined' et obj.prop === undefined sont équivalents, et ils ne distinguent pas ces différentes situations. Et 'prop' in obj peut détecter la situation lorsqu'une propriété n'a pas été définie du tout et ne fait pas attention à la valeur de la propriété qui peut être indéfinie.

Alors que faire?

1) Vous voulez savoir si une propriété est indéfinie par le premier ou le second sens (la situation la plus typique).

obj.prop === undefined // IMHO, see "final fight" below

2) Vous voulez juste savoir si l'objet a une propriété et ne se soucie pas de sa valeur.

'prop' in obj

Remarques:

  • Vous ne pouvez pas vérifier un objet et sa propriété en même temps. Par exemple, ceci x.a === undefined ou ca typeof x.a == 'undefined' soulève ReferenceError: x is not defined si x n'est pas défini.
  • Variable undefined est une variable globale (donc en fait il est window.undefined dans les navigateurs). Il est pris en charge depuis ECMAScript 1st Edition et depuis ECMAScript 5 il est lecture seulement. Donc, dans les navigateurs modernes, il ne peut pas être redéfini à true Comme beaucoup d'auteurs aiment nous faire peur, mais c'est toujours vrai pour les anciens navigateurs.

Combat final: obj.prop === undefined contre typeof obj.prop == 'undefined'

Plus de obj.prop === undefined:

  • C'est un peu plus court et a l'air un peu plus joli
  • Le moteur JavaScript vous donnera une erreur si vous avez mal orthographié undefined

Les moins de obj.prop === undefined:

  • undefined peut être remplacé dans les anciens navigateurs

Plus de typeof obj.prop == 'undefined':

  • C'est vraiment universel! Il fonctionne dans les navigateurs nouveaux et anciens.

Les moins de typeof obj.prop == 'undefined':

  • 'undefned' (mal orthographié) voici juste une chaîne de caractères, donc le moteur JavaScript ne peut pas vous aider si vous l'avez mal orthographié comme je viens de le faire.

Mise à jour (pour le JavaScript côté serveur):

Node.js prend en charge la variable globale undefined comme global.undefined (il peut également être utilisé sans le préfixe 'global'). Je ne connais pas d'autres implémentations de JavaScript côté serveur.


100
2017-08-08 20:28



Le problème se résume à trois cas:

  1. L'objet a la propriété et sa valeur n'est pas undefined.
  2. L'objet a la propriété et sa valeur est undefined.
  3. L'objet n'a pas la propriété.

Cela nous dit quelque chose que je considère important:

Il existe une différence entre un membre indéfini et un membre défini avec une valeur indéfinie.

Mais malheureusement typeof obj.foo ne nous dit pas lequel des trois cas nous avons. Cependant, nous pouvons combiner cela avec "foo" in objdistinguer les cas.

                               |  typeof obj.x === 'undefined' | !("x" in obj)
1.                     { x:1 } |  false                        | false
2.    { x : (function(){})() } |  true                         | false
3.                          {} |  true                         | true

Il vaut la peine de noter que ces tests sont les mêmes pour null entrées aussi

                               |  typeof obj.x === 'undefined' | !("x" in obj)
                    { x:null } |  false                        | false

Je dirais que dans certains cas, il est plus logique (et plus clair) de vérifier si la propriété est présente, que de vérifier si elle est indéfinie, et le seul cas où cette vérification sera différente est le cas 2, le cas rare de une entrée réelle dans l'objet avec une valeur indéfinie.

Par exemple: Je viens de refactoriser un tas de code qui avait un tas de vérifications si un objet avait une propriété donnée.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Ce qui était plus clair lorsqu'il est écrit sans vérification pour indéfini.

if( "x" in blob ) { fn(blob.x); }

Mais comme cela a été mentionné, ils ne sont pas exactement les mêmes (mais sont plus que suffisant pour mes besoins).


59
2018-06-08 04:04



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

Cela a fonctionné pour moi alors que les autres ne l'ont pas fait.


38
2017-07-27 16:03



Je ne suis pas sûr d'où l'origine de l'utilisation === avec typeof vient de, et comme une convention je le vois utilisé dans de nombreuses bibliothèques, mais l'opérateur typeof renvoie un littéral de chaîne, et nous le savons d'avance, alors pourquoi voudriez-vous aussi le vérifier?

typeof x;                      // some string literal "string", "object", "undefined"
if (typeof x === "string") {   // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") {    // sufficient

33
2017-09-22 14:20



Traverser mon répondre de la question connexe Comment vérifier "indéfini" en JavaScript?

Spécifique à cette question, voir les cas de test avec someObject.<whatever>.


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 les tests font la différence quand ils sont dans une enveloppe porté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 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

19
2018-01-13 17:43



Si tu fais

if (myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

il échouera lorsque la variable myvar n'existe pas, car myvar n'est pas défini, donc le script est cassé et le test n'a aucun effet.

Étant donné que l'objet window a une portée globale (objet par défaut) en dehors d'une fonction, une déclaration sera "attachée" à l'objet window.

Par exemple:

var myvar = 'test';

La variable globale myvar est le même que window.myvar ou fenêtre ['myvar']

Pour éviter les erreurs à tester lorsqu'une variable globale existe, il vaut mieux utiliser:

if(window.myvar == undefined )
{ 
    alert('var does not exists or is not initialized');
}

La question de savoir si une variable existe vraiment n'a pas d'importance, sa valeur est incorrecte. Sinon, il est idiot d'initialiser des variables avec undefined, et il vaut mieux utiliser la valeur false pour initialiser. Lorsque vous savez que toutes les variables que vous déclarez sont initialisées avec false, vous pouvez simplement vérifier son type ou compter sur !window.myvar pour vérifier si elle a une valeur correcte / valide. Donc même quand la variable n'est pas définie alors !window.myvar est le même pour myvar = undefined ou myvar = false ou myvar = 0.

Lorsque vous attendez un type spécifique, testez le type de la variable. Pour accélérer le test d'une condition, mieux vaut:

if( !window.myvar || typeof window.myvar != 'string' )
{
    alert('var does not exists or is not type of string');
}

Lorsque la première et simple condition est vraie, l'interprète ignore les tests suivants.

Il est toujours préférable d'utiliser l'instance / objet de la variable pour vérifier si elle a une valeur valide. C'est plus stable et c'est une meilleure façon de programmer.

(y)


14
2017-08-12 14:40