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?
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.
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
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 …
})();
Qu'en est-il de?
var x = {'key': 1};
if ('key' in x) {
console.log('has');
}
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';
};
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
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.
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".
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'
.
if (typeof x.key != "undefined") {
}
Parce que
if (x.key)
échoue si x.key
est résolu en false
(par exemple, x.key = ""
).
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 .
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.
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)
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.
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
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));
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:
alors vous pouvez utiliser:
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
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
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"));
Pourquoi trop compliquer les choses quand vous pouvez le faire:
var isProperty = (objectname.keyname || "") ? true : false;
Simple et clair pour la plupart des cas ...
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.
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:
var obj = {
a:2,
__proto__ :{b:2}
}
console.log('b' in obj)
console.log(Boolean(obj.b))
var obj = {
a:2,
__proto__ :{b:2}
}
console.log(obj.hasOwnProperty('b'))
var obj = {
b : undefined
}
console.log(Boolean(obj.b))
console.log('b' in obj);
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];