Comment vérifier si l'objet a des propriétés en JavaScript?


168

En supposant que je déclare

var ad = {}; 

Comment puis-je vérifier si cet objet contiendra des propriétés définies par l'utilisateur?

Réponses:


86

Vous pouvez parcourir les propriétés de votre objet comme suit:

for(var prop in ad) {
    if (ad.hasOwnProperty(prop)) {
        // handle prop as required
    }
}

Il est important d'utiliser la hasOwnProperty()méthode pour déterminer si l'objet a la propriété spécifiée en tant que propriété directe et non héritée de la chaîne de prototypes de l'objet.

Éditer

À partir des commentaires: vous pouvez mettre ce code dans une fonction et le faire renvoyer false dès qu'il atteint la partie où se trouve le commentaire

Test de performance

Test Of Object.Keys vs For..In Lors du test de toutes les propriétés


2
Salut Daniel, en fait, je cherche un appareil pour vérifier si un objet contient des propriétés définies par l'utilisateur ou non. Ne pas vérifier si une propriété spécifique existe.
Ricky

7
@Ricky: Vous pouvez mettre ce code dans une fonction et le faire renvoyer false dès qu'il atteint la partie où se trouve le commentaire.
Daniel Vassallo

8
Je pense que ces jours-ci, l'utilisation Object.keysserait la plus simple: var a = [1,2,3];a.something=4;console.log(Object.keys(a))parce que cela fait déjà partie de l'ECMA 5, vous pouvez le shimer en toute sécurité: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
HMR

2
Notez que "de nos jours" avec ES5, les objets natifs peuvent avoir des propriétés propres non énumérables, par exemple Object.defineProperty(obj, 'foo', {enumerable:false, value:'foo'}).
RobG

2
Cette solution est un moyen de vérifier les clés qui existent , mais la réponse vraie, efficace et la plus correcte est ci-dessous en utilisant Object.keys (x) .length. Vous n'avez pas besoin de créer votre propre fonction, il en existe déjà une!
dudewad

197

Vous pouvez utiliser la Object.keysméthode intégrée pour obtenir une liste de clés sur un objet et tester sa longueur.

var x = {};
// some code where value of x changes and than you want to check whether it is null or some object with values

if(Object.keys(x).length > 0){
 // Your code here if x has some properties  
}

14
C'est ici la bonne réponse. La réponse acceptée ci-dessus est une solution de contournement et coûte plus cher que la simple vérification du nombre de clés; cela a beaucoup plus de sens .
dudewad

6
Object.keys ("mystring"); donne également des clés qui, à mon avis, ne sont pas souhaitables. Cette réponse est à mon avis incomplète.
Mike de Klerk

2
@MikedeKlerk veuillez le lire attentivement ce n'est pas Object.keys ("mystring"); c'est Object.keys (objectVariableName) qui retournera un tableau de toutes les clés de l'objet. ex: {'x': 'abc', 'y': 'def'} ce sera ['x', 'y']
Dhaval Chaudhary

3
@DhavalChaudhary Merci pour votre réponse à mon commentaire. Quand j'essaye ce code var str = "MyString"; Object.keys(str);, la console sort 8 touches, de 0 à 7, pour chaque caractère. Ou est-ce que je ne comprends toujours pas la réponse.
Mike de Klerk le

6
@MikedeKlerk mais ce n'est qu'une solution pour les objets et non pour les chaînes, veuillez vous référer à la question.
Dhaval Chaudhary

111

Qu'en est-il de créer une fonction simple?

function isEmptyObject(obj) {
  for(var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
  }
  return true;
}

isEmptyObject({}); // true
isEmptyObject({foo:'bar'});  // false

L' hasOwnPropertyappel de méthode directement sur le Object.prototypen'est qu'ajouter un peu plus de sécurité , imaginez ce qui suit en utilisant un obj.hasOwnProperty(...)appel normal :

isEmptyObject({hasOwnProperty:'boom'});  // false

Remarque: (pour le futur) La méthode ci-dessus repose sur l' for...ininstruction, et cette instruction n'itère que sur les propriétés énumérables , dans la norme ECMAScript la plus largement implémentée actuellement (3e édition), le programmeur n'a aucun moyen de créer des propriétés non énumérables .

Cependant, cela a changé maintenant avec ECMAScript 5e édition , et nous sommes en mesure de créer des propriétés non énumérables, non inscriptibles ou non supprimables, de sorte que la méthode ci-dessus peut échouer , par exemple:

var obj = {};
Object.defineProperty(obj, 'test', { value: 'testVal', 
  enumerable: false,
  writable: true,
  configurable: true
});
isEmptyObject(obj); // true, wrong!!
obj.hasOwnProperty('test'); // true, the property exist!!

Une solution ECMAScript 5 à ce problème serait:

function isEmptyObject(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

La Object.getOwnPropertyNamesméthode retourne un Arraycontenant les noms de toutes les propriétés propres d'un objet, énumérables ou non , cette méthode est maintenant implémentée par les fournisseurs de navigateurs, elle est déjà sur la version bêta de Chrome 5 et le dernier WebKit Nightly Builds.

Object.defineProperty est également disponible sur ces navigateurs et sur les dernières versions de Firefox 3.7 Alpha.


1
Quel est l'avantage de Object.prototype.hasOwnProperty.call (obj, prop) par rapport à obj.hasOwnProperty (prop)?
Casey Chu

3
@Casey, édité, si un objet remplace la hasOwnPropertypropriété, la fonction risque de planter ... Je sais que je suis un peu paranoïaque ... mais parfois vous ne savez pas dans quel type d'environnement votre code sera utilisé, mais vous savez quelle méthode vous voulez utiliser ...
CMS

2
+1 pour avoir répondu à cette question ... et à d'autres questions du futur! :)
Daniel Vassallo

1
Notez qu'il existe également un bogue dans IE où si vous avez une propriété avec un nom qui correspond à une propriété non énumérable dans Object.prototype, elle n'est pas énumérée par for...in. Donc isEmptyObject({toString:1})va échouer. C'est l'une des raisons malheureuses que vous ne pouvez pas tout à fait utiliser Objectcomme cartographie à usage général.
bobince

1
@ MichaelMartin-Smucker - les clés ne renvoient que des propriétés propres énumérables, donc elles ne conviennent pas ici.
RobG

58

Avec jQuery, vous pouvez utiliser:

$.isEmptyObject(obj); // Returns: Boolean

Depuis jQuery 1.4, cette méthode vérifie à la fois les propriétés de l'objet lui-même et les propriétés héritées des prototypes (en ce sens qu'elle n'utilise pas hasOwnProperty).

Avec ECMAScript 5th Edition dans les navigateurs modernes (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +), vous pouvez utiliser la méthode Object.keys intégrée :

var obj = { blah: 1 };
var isEmpty = !Object.keys(obj).length;

Ou tout vieux JavaScript:

var isEmpty = function(obj) {
               for(var p in obj){
                  return false;
               }
               return true;
            };



11

Si vous êtes prêt à utiliser lodash , vous pouvez utiliser la someméthode.

_.some(obj) // returns true or false

Voir ce petit exemple jsbin


var x = [1,2] // true
djv

@damionjn J'ai ajouté votre code à l'exemple. Je vois votre point avec le tableau renvoyant la mauvaise réponse, mais OP a initialement déclaré une variable en tant qu'objet, donc je pense que c'est bien de supposer cela. Il y a une réponse ci-dessus qui utilise la méthode des traits de soulignement isEmpty (lodash a la même méthode). Cette réponse pose exactement le même problème. Si vous donnez à isEmpty un tableau non vide, vous obtiendrez également un mauvais résultat.
sfs

Assez juste, mais nous devrions fournir des réponses avec toutes les bases couvertes pour être sûrs des meilleures pratiques. Vous avez raison, je suis passé juste à côté de sa réponse sans aucune critique. Pour tous ceux qui passent, ce n'est pas une méthode dédiée aux objets. _.some([1, 2]) // true Assurez-vous de vérifier d'abord: stackoverflow.com/a/13356338/1922747
djv

5
for (var hasProperties in ad) break;
if (hasProperties)
    ... // ad has properties

Si vous devez être prudent et vérifier les prototypes d'objets (ceux-ci sont ajoutés par certaines bibliothèques et pas là par défaut):

var hasProperties = false;
for (var x in ad) {
    if (ad.hasOwnProperty(x)) {
        hasProperties = true;
        break;
    }
}
if (hasProperties)
    ... // ad has properties

1
dans votre solution, il n'y a pas de filtrage des propriétés de prototype indésirables, ce qui signifie qu'il peut se comporter mal lors de l'utilisation d'une bibliothèque telle que Prototype.js ou lorsqu'un utilisateur inexpérimenté a ajouté des propriétés de prototype supplémentaires à l'objet. Découvrez la solution Daniels sur cette page.
Joscha

Vous n'avez pas besoin d'utiliser une bibliothèque ou d'être inexpérimenté pour étendre le prototype d'un objet. Certains programmeurs expérimentés le font tout le temps.
Alsciende

2
for(var memberName in ad)
{
  //Member Name: memberName
  //Member Value: ad[memberName]
}

Membre signifie propriété de membre, variable de membre, comme vous voulez l'appeler> _>

Le code ci-dessus renverra TOUT, y compris toString ... Si vous voulez seulement voir si le prototype de l'objet a été étendu:

var dummyObj = {};  
for(var memberName in ad)
{
  if(typeof(dummyObj[memberName]) == typeof(ad[memberName])) continue; //note A
  //Member Name: memberName
  //Member Value: ad[memberName]

}

Note A: Nous vérifions si le membre de l'objet factice a le même type que le membre de notre objet de test. S'il s'agit d'une extension, le type de membre dummyobject doit être "indéfini"


Salut, puis-je simplement savoir si un objet contient des propriétés ou non? Merci
Ricky

dans votre solution, il n'y a pas de filtrage des propriétés de prototype indésirables, ce qui signifie qu'il peut se comporter mal lors de l'utilisation d'une bibliothèque telle que Prototype.js ou lorsqu'un utilisateur inexpérimenté a ajouté des propriétés de prototype supplémentaires à l'objet.
Joscha

Découvrez la solution Daniels sur cette page - elle est moins sujette aux erreurs!
Joscha

2
Votre premier bloc de code ne le couvre pas du tout. le deuxième bloc de code se comporte mal si j'ajoute une variable à l'objet "ad" qui n'est pas défini. Vraiment, consultez la réponse de Daniels, c'est la seule bonne et rapide, car elle utilise une implémentation native appelée "hasOwnProperty".
Joscha

@Ricky: Si vous voulez vérifier si un objet contient des propriétés, vous pouvez simplement utiliser l'exemple dans ma réponse: stackoverflow.com/questions/2673121/… . Si le code atteint le commentaire, votre objet n'aura aucune propriété directe. Sinon, ce serait le cas.
Daniel Vassallo

2
var hasAnyProps = false; for (var key in obj) { hasAnyProps = true; break; }
// as of this line hasAnyProps will show Boolean whether or not any iterable props exist

Simple, fonctionne dans tous les navigateurs, et même s'il s'agit techniquement d'une boucle pour toutes les clés de l'objet, il ne les parcourt PAS toutes ... soit il y a 0 et la boucle ne s'exécute pas, soit il y en a et il se brise après le premier un (parce que tout ce que nous vérifions, c'est s'il y en a un ... alors pourquoi continuer?)


1

Réponse très tardive, mais c'est ainsi que vous pourriez le gérer avec des prototypes.

Array.prototype.Any = function(func) {
    return this.some(func || function(x) { return x });
}

Object.prototype.IsAny = function() {
    return Object.keys(this).Any();
}

0

Lorsque vous êtes sûr que l'objet est défini par l'utilisateur, le moyen le plus simple de déterminer si UDO est vide serait le code suivant:

isEmpty=
/*b.b Troy III p.a.e*/
function(x,p){for(p in x)return!1;return!0};

Même si cette méthode est (par nature) déductive, - c'est la plus rapide et la plus rapide possible.

a={};
isEmpty(a) >> true

a.b=1
isEmpty(a) >> false 

ps:! ne l'utilisez pas sur des objets définis par le navigateur.


... retourne 0; return 1}; serait le même?
commonpike

1
@pike no, return! 1; return! 0
Christophe

0

Réponse tardive, mais certains frameworks traitent les objets comme des énumérables. Par conséquent, bob.js peut le faire comme ceci:

var objToTest = {};
var propertyCount = bob.collections.extend(objToTest).count();

0

Vous pouvez utiliser les éléments suivants:

Double coup !! recherche de propriété

var a = !![]; // true
var a = !!null; // false

hasOwnProperty C'est quelque chose que j'utilisais:

var myObject = {
  name: 'John',
  address: null
};
if (myObject.hasOwnProperty('address')) { // true
  // do something if it exists.
}

Cependant, JavaScript a décidé de ne pas protéger le nom de la méthode, afin qu'elle puisse être falsifiée.

var myObject = {
  hasOwnProperty: 'I will populate it myself!'
};

prop dans myObject

var myObject = {
  name: 'John',
  address: null,
  developer: false
};
'developer' in myObject; // true, remember it's looking for exists, not value.

Type de

if (typeof myObject.name !== 'undefined') {
  // do something
}

Cependant, il ne vérifie pas la valeur null.

Je pense que c'est la meilleure façon.

en opérateur

var myObject = {
  name: 'John',
  address: null
};

if('name' in myObject) {
  console.log("Name exists in myObject");
}else{
  console.log("Name does not exist in myObject");
}

résultat:

Le nom existe dans myObject

Voici un lien qui donne plus de détails sur l'opérateur in: Déterminer si une propriété d'objet existe


0

Fonction ES6

/**
 * Returns true if an object is empty.
 * @param  {*} obj the object to test
 * @return {boolean} returns true if object is empty, otherwise returns false
 */
const pureObjectIsEmpty = obj => obj && obj.constructor === Object && Object.keys(obj).length === 0

Exemples:


let obj = "this is an object with String constructor"
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {}
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = []
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = [{prop:"value"}]
console.log(pureObjectIsEmpty(obj)) // empty? true

obj = {prop:"value"}
console.log(pureObjectIsEmpty(obj)) // empty? false

-1

Que dis-tu de ça?

var obj = {},
var isEmpty = !obj;
var hasContent = !!obj

Cette réponse ne répond pas à la question. OP demande si un objet contient des propriétés définies par l'utilisateur - votre réponse vérifie si l'objet lui-même sera converti en une valeur booléenne fausse.
Jasmonate

... et j'ai aussi réalisé plus tard que James avait déjà inclus cette option dans sa réponse. Désolé les gars.
Peter Toth
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.