web-dev-qa-db-fra.com

Comment vérifier si un objet a une propriété en JavaScript?

Comment vérifier si un objet a une propriété en JavaScript?

Considérer:

x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
    //Do this
}

Est-ce la meilleure façon de le faire?

1272
sheats

Je suis vraiment déconcerté par les réponses qui ont été données - la plupart d'entre elles sont carrément incorrectes. Bien sûr, vous pouvez avoir des propriétés d'objet ayant des valeurs indéfinies, NULL ou false. Donc, réduire simplement le contrôle de propriété à typeof this[property] ou, pire encore, x.key vous donnera des résultats totalement trompeurs.

Cela dépend de ce que vous recherchez. Si vous voulez savoir si un objet contient physiquement une propriété (et qu'elle ne vient pas de quelque part dans la chaîne de prototypes), alors object.hasOwnProperty est la voie à suivre. Tous les navigateurs modernes le supportent. (Il manquait dans les anciennes versions de Safari - 2.0.1 et antérieures - mais ces versions du navigateur sont rarement utilisées.)

Si ce que vous recherchez, c'est si un objet a une propriété qui est itérable (lorsque vous parcourez les propriétés de l'objet, il apparaît), alors: prop in object vous donnera l'effet souhaité.

Puisque vous préférez probablement utiliser hasOwnProperty, et compte tenu du fait que vous souhaitiez utiliser une méthode de secours, je vous présente la solution suivante:

var obj = {
    a: undefined,
    b: null,
    c: false
};

// a, b, c all found
for ( var prop in obj ) {
    document.writeln( "Object1: " + prop );
}

function Class(){
    this.a = undefined;
    this.b = null;
    this.c = false;
}

Class.prototype = {
    a: undefined,
    b: true,
    c: true,
    d: true,
    e: true
};

var obj2 = new Class();

// a, b, c, d, e found
for ( var prop in obj2 ) {
    document.writeln( "Object2: " + prop );
}

function hasOwnProperty(obj, prop) {
    var proto = obj.__proto__ || obj.constructor.prototype;
    return (prop in obj) &&
        (!(prop in proto) || proto[prop] !== obj[prop]);
}

if ( Object.prototype.hasOwnProperty ) {
    var hasOwnProperty = function(obj, prop) {
        return obj.hasOwnProperty(prop);
    }
}

// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
    if ( hasOwnProperty(obj2, prop) ) {
        document.writeln( "Object2 w/ hasOwn: " + prop );
    }
}

Ce qui précède est une solution multi-navigateur fonctionnelle pour hasOwnProperty, avec une mise en garde: il est impossible de faire la distinction entre les cas où une propriété identique est présente sur le prototype et sur l'instance - elle suppose simplement qu'elle provient du prototype. Vous pouvez le changer pour qu'il soit plus indulgent ou plus strict, en fonction de votre situation, mais à tout le moins, cela devrait être plus utile.

1270
John Resig

Avec Underscore.js ou ( encore mieux ) lodash :

_.has(x, 'key');

Lequelle appelle Object.prototype.hasOwnProperty, mais (a) est plus courte à taper et (b) utilise "une référence sûre à hasOwnProperty" (c’est-à-dire que cela fonctionne même si hasOwnProperty est écrasé).

En particulier, lodash définit _.has comme:

   function has(object, key) {
      return object ? hasOwnProperty.call(object, key) : false;
   }
   // hasOwnProperty = Object.prototype.hasOwnProperty
252
Brian M. Hunt

Note: ce qui suit est aujourd'hui largement obsolète grâce au mode strict, et hasOwnProperty. La solution correcte consiste à utiliser le mode strict et à vérifier la présence d'une propriété à l'aide de obj.hasOwnProperty. Cette réponse précède ces deux choses, du moins aussi largement implémentées (oui, elle est aussi ancienne). Prenez ce qui suit comme une note historique.


N'oubliez pas que undefined est (malheureusement) pas un mot réservé en JavaScript si vous n'utilisez pas le mode strict. Par conséquent, quelqu'un (quelqu'un d'autre, évidemment) pourrait avoir la grande idée de le redéfinir, de casser votre code.

Une méthode plus robuste est donc la suivante:

if (typeof(x.attribute) !== 'undefined')

D'un autre côté, cette méthode est beaucoup plus détaillée et plus lente. : - /

Une alternative courante consiste à s'assurer que undefined est réellement non défini, par exemple. en plaçant le code dans une fonction qui accepte un paramètre supplémentaire, appelé undefined, qui n’a pas transmis de valeur. Pour vous assurer qu’une valeur n’est pas transmise, vous pouvez simplement l’appeler vous-même immédiatement, par exemple:

(function (undefined) {
    … your code …
    if (x.attribute !== undefined)
        … mode code …
})();
112
Konrad Rudolph

Qu'en est-il de?

var x = {'key': 1};

if ('key' in x) {
    console.log('has');
}
105
Whisher
if (x.key !== undefined)

Armin Ronacher semble avoir déjà me battre , mais:

Object.prototype.hasOwnProperty = function(property) {
    return this[property] !== undefined;
};

x = {'key': 1};

if (x.hasOwnProperty('key')) {
    alert('have key!');
}

if (!x.hasOwnProperty('bar')) {
    alert('no bar!');
}

Une solution plus sûre mais plus lente, comme indiqué par Konrad Rudolph et Armin Ronacher serait:

Object.prototype.hasOwnProperty = function(property) {
    return typeof this[property] !== 'undefined';
};
41
enobrev

Vous pouvez utiliser l'opérateur in pour vérifier si la propriété existe sur un objet:

x = {'key': 1};
alert("key" in x);

Vous pouvez également parcourir toutes les propriétés de l'objet à l'aide d'une boucle for - in, puis rechercher la propriété spécifique:

for (prop in x) {
    if (prop == "key") {
        //Do something
    }
}

Vous devez déterminer si cette propriété d'objet est énumérable ou non, car les propriétés non énumérables ne s'afficheront pas dans une boucle for-in. De même, si la propriété énumérable masque une propriété non énumérable du prototype, elle n'apparaîtra pas dans Internet Explorer 8 et les versions antérieures.

Si vous souhaitez une liste de toutes les propriétés d’instance, énumérables ou non, vous pouvez utiliser

Object.getOwnPropertyNames(x);

Cela retournera un tableau de noms de toutes les propriétés qui existent sur un objet.

Enfin, vous pouvez utiliser l'opérateur typeof pour vérifier directement le type de données de la propriété d'objet:

if (typeof x.key == "undefined") {
    alert("undefined");
}

Si la propriété n'existe pas sur l'objet, la chaîne ne sera pas définie. Sinon, il retournera le type de propriété approprié. Toutefois, notez que ce n'est pas toujours un moyen valide de vérifier si un objet a une propriété ou non, car vous pourriez avoir une propriété définie sur non définie, auquel cas, utiliser typeof x.key renverrait toujours la valeur true toujours dans l'objet).

Mise à jour: vous pouvez vérifier si une propriété existe en comparant la propriété javascript non définie 

if (x.key === undefined) {
    alert("undefined");
}

Cela devrait fonctionner à moins que la clé n'ait été spécifiquement définie sur undefined sur l'objet x

33
goonerify

Coupons à travers une certaine confusion ici. Commençons par simplifier en supposant que hasOwnProperty existe déjà; c'est le cas de la grande majorité des navigateurs actuellement utilisés.

hasOwnProperty renvoie true si le nom d'attribut qui lui est transmis a été ajouté à l'objet. Il est entièrement indépendant de la valeur réelle qui lui est attribuée, qui peut être exactement undefined.

Par conséquent:

var o = {}
o.x = undefined

var a = o.hasOwnProperty('x')  // a is true
var b = o.x === undefined // b is also true

Toutefois:

var o = {}

var a = o.hasOwnProperty('x')  // a is now false
var b = o.x === undefined // b is still true

Le problème est ce qui se produit lorsqu'un objet de la chaîne de prototypes possède un attribut avec la valeur indéfinie? hasOwnProperty sera faux pour elle, et donc !== undefined. Cependant, for..in le listera toujours dans l'énumération.

En bout de ligne, il n’existe aucun moyen (selon Internet Explorer, __prototype__) permettant à plusieurs navigateurs de déterminer qu’un identifiant spécifique n’a pas été attaché à un objet ni à aucun élément de sa chaîne de prototypes.

26
AnthonyWJones

Si vous recherchez une propriété, alors "NON". Tu veux:

if ('prop' in obj) { }

En général, vous ne devez pas vous soucier de savoir si la propriété provient ou non du prototype ou de l'objet.

Cependant, comme vous avez utilisé "clé" dans votre exemple de code, il semble que vous traitiez l'objet comme un hachage, auquel cas votre réponse serait logique. Toutes les clés de hachage sont des propriétés dans l'objet et vous évitez les propriétés supplémentaires fournies par le prototype.

La réponse de John Resig était très complète, mais je pensais que ce n'était pas clair. Surtout quand utiliser "'prop' in obj".

17
Gerard ONeill

Oui, c’est :) Je pense que vous pouvez aussi utiliser Object.prototype.hasOwnProperty.call(x, 'key') qui devrait également fonctionner si x a une propriété appelée hasOwnProperty :)

Mais cela teste pour ses propres propriétés. Si vous voulez vérifier si elle possède une propriété qui peut également être héritée, vous pouvez utiliser typeof x.foo != 'undefined'.

12
Armin Ronacher
if (typeof x.key != "undefined") {

}

Parce que

if (x.key)

échoue si x.key est résolu en false (par exemple, x.key = "").

12
werehamster

Vous pouvez également utiliser l'objet ES6 Reflect :

x = {'key': 1};
Reflect.has( x, 'key'); // returns true

La documentation sur MDN pour Reflect.has se trouve ici .

La méthode statique Reflect.has() fonctionne comme l’opérateur in .

10
Wilt

Pour tester des objets simples, utilisez: if (obj[x] !== undefined)

Si vous ne connaissez pas le type d'objet utilisé, utilisez: if (obj.hasOwnProperty(x))

Toutes les autres options sont plus lentes.

Détails

Evaluation de la performance de 100 000 000 de cycles sous Nodejs aux 5 options suggérées par d’autres ici:

function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }

L'évaluation nous indique que, sauf si nous voulons vérifier spécifiquement le prototype de la chaîne de l'objet ainsi que l'objet lui-même, nous ne devrions pas utiliser la forme commune suivante: if (X in Obj)... Il est 2 à 6 fois plus lent en fonction du cas d'utilisation  

hasKey1 execution time: 4s 510.427785ms
hasKey2 execution time: 0s 904.374806ms
hasKey3 execution time: 0s 760.336193ms
hasKey4 execution time: 0s 935.19901ms
hasKey5 execution time: 2s 148.189608ms

En bout de ligne, si votre objet n'est pas nécessairement un objet simple et que vous souhaitez éviter de vérifier la chaîne du prototype de l'objet et vous assurer que x appartient directement à un objet, utilisez "if (obj.hasOwnProperty (x)) ...".

Sinon, lorsque vous utilisez un objet simple sans vous soucier de la chaîne de prototypes de l'objet, utiliser if (typeof(obj[x]) !== 'undefined')... est le moyen le plus sûr et le plus rapide. 

Si vous utilisez un objet simple comme table de hachage et ne faites jamais rien de crétin, j'utiliserais if (obj[x])... car je le trouve beaucoup plus lisible.

S'amuser.

10
davidhadas

OK, il semble que j'ai la bonne réponse, sauf si vous ne voulez pas de propriétés héritées

if (x.hasOwnProperty('key'))

Voici quelques autres options pour inclure les propriétés héritées:

if (x.key) // Quick and dirty, but it does the same thing as below.

if (x.key !== undefined)
7
sheats

hasOwnProperty "peut être utilisé pour déterminer si un objet a la propriété spécifiée comme propriété directe de cet objet; contrairement à l'opérateur in , cette méthode ne vérifie pas la chaîne de prototypes de l'objet." 

Donc très probablement, pour ce qui semble être votre question, vous ne voulez pas utiliser hasOwnProperty, qui détermine si la propriété existe comme attaché directement à l'objet lui-même ,.

Si vous souhaitez déterminer si la propriété existe dans la chaîne de prototypes que vous souhaitez utiliser, par exemple:

if( prop in object ){ // do something }

J'espère que ça aide.

5
rogopag

Un autre moyen relativement simple consiste à utiliser Object.keys . Cela retourne une array, ce qui signifie que vous obtenez toutes les fonctionnalités d'un tableau.

var noInfo = {};
var info = {something: 'data'};

Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true

Bien que nous soyons dans un monde avec un support de navigateur excellent. Parce que cette question est si ancienne, j'ai pensé ajouter ceci: Ceci est sûr à utiliser à partir de JS v1.8.5

4
Jamie Hutber

Ne faites pas ceci object.hasOwnProperty(key)), c'est vraiment mauvais parce que ces méthodes peuvent être masquées par les propriétés de l'objet en question (considérez { hasOwnProperty: false }) ou l'objet peut être un objet null (Object.create(null)).

Le meilleur moyen est de faire Object.prototype.hasOwnProperty.call(object, key) ou:

const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
/* or */
import has from 'has'; // https://www.npmjs.com/package/has
// ...
console.log(has.call(object, key));
3
Abdullah Danyal

Avec le risque de vote massif en aval, voici une autre option pour un cas spécifique. :)

Si vous souhaitez tester un membre sur un objet et savoir s'il a été défini sur autre chose que:

  • ''
  • false
  • nul
  • undefined
  • 0 ...

alors vous pouvez utiliser:

var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
        // member is set, do something
}
2
arkod

Solution ECMAScript 6 avec réflexion. Créer un wrapper comme:

/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj    The object or array to be searched.
@param key    The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
   "use strict";
   var retVal = (typeof defVal === 'undefined' ? "" : defVal);
   if ( Reflect.has( obj, key) ) {
       return Reflect.get( obj, key);
   }
   return retVal;
}  // getSafeReflectArg
2
Harm

Il existe une méthode "hasOwnProperty" existe sur l'objet, mais il n'est pas recommandé d'appeler cette méthode directement car l'objet est parfois null ou qu'une propriété existe sur l'objet comme: { hasOwnProperty: false }

Donc, mieux serait:

// good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));

// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));

2

Pourquoi trop compliquer les choses quand vous pouvez le faire:

var isProperty =  (objectname.keyname || "") ? true : false;

Simple et clair pour la plupart des cas ...

1
Alex

Vous devez utiliser la méthode object.hasOwnProperty(property). Il renvoie true si l'objet a la propriété et false si ce n'est pas le cas.

1
John Anisere

Vous pouvez utiliser les approches suivantes- 

var obj = {a:1}
console.log('a' in obj)               //1
console.log(obj.hasOwnProperty('a'))  //2
console.log(Boolean(obj.a))         //3

La différence entre les approches suivantes sont les suivantes: 

  1. En 1ère et 3ème approche, nous ne cherchons pas seulement dans un objet, mais aussi sa chaîne prototypique Si l'objet n'a pas la propriété mais que La propriété est présente dans sa chaîne de prototypes, elle va donner True. 

 var obj = {
      a:2,
      __proto__ :{b:2}
    }

    console.log('b' in obj)
    console.log(Boolean(obj.b))

  1. 2ème approche vérifiera uniquement pour ses propres propriétés. Ex - 

var obj = {
      a:2,
      __proto__ :{b:2}
    }

    console.log(obj.hasOwnProperty('b'))

  1. La différence entre 1er et troisième est qu'il existe une propriété qui a une valeur indéfinie, la 3ème approche va donner false alors que la première donnera true. 

var obj = {
      b : undefined
    }
    console.log(Boolean(obj.b))
    console.log('b' in obj);

0
Komal Bansal

Si la clé que vous vérifiez est stockée dans une variable , vous pouvez la vérifier comme ceci:

x = {'key': 1};
y = 'key';
x[y];
0
Steven Penny