Comment déterminer si un objet a une propriété donnée en JavaScript

311

Comment puis-je déterminer si un objet xa une propriété définie y, quelle que soit la valeur de x.y?

J'utilise actuellement

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

mais cela semble un peu maladroit. Y a-t-il une meilleure façon?

royhowie
la source

Réponses:

584

L'objet a une propriété:

Si vous testez des propriétés qui se trouvent sur l'objet lui-même (ne faisant pas partie de sa chaîne de prototypes), vous pouvez utiliser .hasOwnProperty():

if (x.hasOwnProperty('y')) { 
  // ......
}

L'objet ou son prototype a une propriété:

Vous pouvez également utiliser l' inopérateur pour tester les propriétés héritées.

if ('y' in x) {
  // ......
}
gnarf
la source
23
Ou encore mieux - Object.prototype.hasOwnProperty.call(x, 'y'), de sorte que la propriété nommée "hasOwnProperty" n'entre pas en conflit avec le processus d'inspection;)
kangax
4
Ou encore plus court - {}.hasOwnProperty.call(x, 'y').
axmrnv
78

Si vous voulez savoir si l'objet contient physiquement la réponse de la propriété @ gnarf en utilisant hasOwnPropertyfera le travail.

Si vous voulez savoir si la propriété existe n'importe où, soit sur l'objet lui-même, soit dans la chaîne du prototype, vous pouvez utiliser l' inopérateur .

if ('prop' in obj) {
  // ...
}

Par exemple.:

var obj = {};

'toString' in obj == true; // inherited from Object.prototype
obj.hasOwnProperty('toString') == false; // doesn't contains it physically
CMS
la source
18

Underscore.js ou Lodash

if (_.has(x, "y")) ...

:)

nackjicholson
la source
Nan. C'est juste un alias pour Object.prototype.hasOwnProperty.call(x, "y"). Pour les tableaux , je pense que vous voudrez peut - être Array.prototype.indexOf, _.indexOfou_.contains
nackjicholson
13

Vous pouvez réduire cela un peu comme ceci:

if ( x.y !== undefined ) ...
jpsimons
la source
15
Cela échouerait avecx = {y:undefined}
James
20
Quelqu'un doit-il faire la distinction entre «non défini» et «défini comme non défini»?
jpsimons
16
@darkporter je fais parfois;)
mmm
6

Une caractéristique de mon code d'origine

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

ce qui peut être utile dans certaines situations, c'est qu'il est sûr d'utiliser qu'il xexiste ou non. Avec l'une ou l'autre des méthodes de la réponse de gnarf, il faut d'abord tester xs'il existe un doute quant à son existence.

Alors peut-être que les trois méthodes ont leur place dans leur sac de trucs.


la source
Vous pouvez toujours utiliser (x && x.hasOwnProperty('y'))ou(x && 'y' in x)
gnarf
Je suis d'accord, le test de x devrait être un cas distinct en soi. Donne également un meilleur rapport d'erreurs.
b01
Cela a échoué pour moi. Si x n'est pas défini, alors typeof (xy) renvoie un ReferenceErrorplutôt que la chaîne «non défini»
Craig
1

Étant donné que la question concernait la lourdeur de la vérification des propriétés, et une utilisation régulière pour cela étant la validation des objets d'options d'argument de fonction, j'ai pensé mentionner un moyen court sans bibliothèque de tester l'existence de plusieurs propriétés. Avertissement: il nécessite ECMAScript 5 (mais IMO toute personne utilisant encore IE8 mérite un site Web cassé).

function f(opts) {
  if(!["req1","req2"].every(opts.hasOwnProperty, opts)) {
      throw new Error("IllegalArgumentException");
  }
  alert("ok");
}
f({req1: 123});  // error
f({req1: 123, req2: 456});  // ok
stt
la source
-2

Pourquoi pas simplement:

if (typeof myObject.myProperty == "undefined") alert("myProperty is not defined!");

Ou si vous attendez un type spécifique:

if (typeof myObject.myProperty != "string") alert("myProperty has wrong type or does not exist!");
Dôme
la source
1
Parce que c'est mauvais à lire et pas à taper strict. Je dois vous demander: pourquoi pas simplement x.hasOwnProperty('y')?
Fabian Picone