Question L'objet est-il vide? [dupliquer]


Cette question a déjà une réponse ici:

Quel est le moyen le plus rapide de vérifier si un objet est vide ou non?

Y a-t-il un moyen plus rapide et meilleur que cela:

function count_obj(obj){
    var i = 0;
    for(var key in obj){
        ++i;
    }

    return i;
}

423
2018-02-14 15:53


origine


Réponses:


Je suppose que par vide vous voulez dire "n'a pas de propriétés propres".

// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;

function isEmpty(obj) {

    // null and undefined are "empty"
    if (obj == null) return true;

    // Assume if it has a length property with a non-zero value
    // that that property is correct.
    if (obj.length > 0)    return false;
    if (obj.length === 0)  return true;

    // If it isn't an object at this point
    // it is empty, but it can't be anything *but* empty
    // Is it empty?  Depends on your application.
    if (typeof obj !== "object") return true;

    // Otherwise, does it have any properties of its own?
    // Note that this doesn't handle
    // toString and valueOf enumeration bugs in IE < 9
    for (var key in obj) {
        if (hasOwnProperty.call(obj, key)) return false;
    }

    return true;
}

Exemples:

isEmpty(""), // true
isEmpty(33), // true (arguably could be a TypeError)
isEmpty([]), // true
isEmpty({}), // true
isEmpty({length: 0, custom_property: []}), // true

isEmpty("Hello"), // false
isEmpty([1,2,3]), // false
isEmpty({test: 1}), // false
isEmpty({length: 3, custom_property: [1,2,3]}) // false

Si vous avez seulement besoin de gérer Navigateurs ECMAScript5, vous pouvez utiliser Object.getOwnPropertyNames à la place du hasOwnProperty boucle:

if (Object.getOwnPropertyNames(obj).length > 0) return false;

Cela garantira que même si l'objet n'a que des propriétés non énumérables isEmpty vous donnera toujours les résultats corrects.


408
2018-02-14 15:57



Pour ECMAScript5 (pas encore supporté dans tous les navigateurs), vous pouvez utiliser:

Object.keys(obj).length === 0

491
2018-02-14 15:59



MODIFIER: Notez que vous devriez probablement utiliser Solution ES5 au lieu de cela, car le support ES5 est répandu ces jours-ci. Cela fonctionne toujours pour jQuery cependant.


Manière simple et multi-navigateur est en utilisant jQuery.isEmptyObject:

if ($.isEmptyObject(obj))
{
    // do something
}

Plus: http://api.jquery.com/jQuery.isEmptyObject/

Vous avez besoin de jquery.


213
2018-05-28 09:07



Souligner et lodash chacun a un pratique isEmpty() fonction, si cela ne vous dérange pas d'ajouter une bibliothèque supplémentaire.

_.isEmpty({});

88
2018-02-02 22:27



Mettons ce bébé au lit; testé sous Node, Chrome, Firefox et IE 9, il devient évident que pour la plupart des cas d'utilisation:

  • (pour ... dans ...) est l'option la plus rapide à utiliser!
  • Object.keys (obj) .length est 10 fois plus lent pour les objets vides
  • JSON.stringify (obj) .length est toujours le plus lent (pas étonnant)
  • Object.getOwnPropertyNames (obj) .length prend plus de temps que Object.keys (obj) .length peut être beaucoup plus long sur certains systèmes.

Performance de la ligne inférieure, utilisez:

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

ou

function isEmpty(obj) {
   for (var x in obj) { if (obj.hasOwnProperty(x))  return false; }
   return true;
}

Résultats sous le nœud:

  • premier résultat: return (Object.keys(obj).length === 0)
  • deuxième résultat: for (var x in obj) { return false; }...
  • troisième résultat: for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
  • quatrième résultat: return ('{}' === JSON.stringify(obj))

Test d'objet avec 0 touches 0.00018 0.000015 0.000015 0,000324

Test d'objet avec 1 clé 0.000346 0.000458 0,000577 0.000657

Test d'objet avec 2 clés 0.000375 0.00046 0,000565 0.000773

Test d'objet avec 3 clés 0.000406 0.000476 0.000577 0.000904

Test d'objet avec 4 clés 0.000435 0.000487 0,000589 0.001031

Test d'objet avec 5 clés 0.000465 0.000501 0.000604 0.001148

Test d'objet avec 6 clés 0,000492 0.000511 0.000618 0.001269

Test d'objet avec 7 clés 0.000528 0.000527 0.000637 0,00138

Test de l'objet avec 8 clés 0,000565 0.000538 0.000647 0,00159

Test d'objet avec 100 clés 0,003718 0,00243 0.002535 0.01381

Test de l'objet avec 1000 clés 0.0337 0.0193 0.0194 0.1337

Notez que si votre cas d'utilisation type teste un objet non vide avec peu de clés et que vous essayez rarement de tester des objets ou des objets vides avec 10 clés ou plus, tenez compte de l'option Object.keys (obj) .length. - sinon, allez avec l'implémentation plus générique (pour ... dans ...).

Notez que Firefox semble avoir un support plus rapide pour Object.keys (obj) .length et Object.getOwnPropertyNames (obj) .length, ce qui en fait un meilleur choix pour tout objet non vide, mais quand il s'agit d'objets vides, le ( pour ... en ...) est simplement 10 fois plus rapide.

Mon 2 cents est que Object.keys (obj) .length est une mauvaise idée car il crée un objet de clés juste pour compter combien de clés sont à l'intérieur, que de le détruire! Afin de créer cet objet, il doit boucler les clés ... alors pourquoi l'utiliser et non l'option (pour ... dans ...) :)

var a = {};

function timeit(func,count) {
   if (!count) count = 100000;
   var start = Date.now();
   for (i=0;i<count;i++) func();
   var end = Date.now();
   var duration = end - start;
   console.log(duration/count)
}

function isEmpty1() {
    return (Object.keys(a).length === 0)
}
function isEmpty2() {
    for (x in a) { return false; }
    return true;
}
function isEmpty3() {
    for (x in a) { if (a.hasOwnProperty(x))  return false; }
    return true;
}
function isEmpty4() {
    return ('{}' === JSON.stringify(a))
}


for (var j=0;j<10;j++) {
   a = {}
   for (var i=0;i<j;i++) a[i] = i;
   console.log('Testing for Object with '+Object.keys(a).length+' keys')
   timeit(isEmpty1);
   timeit(isEmpty2);
   timeit(isEmpty3);
   timeit(isEmpty4);
}

a = {}
for (var i=0;i<100;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4, 10000);

a = {}
for (var i=0;i<1000;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1,10000);
timeit(isEmpty2,10000);
timeit(isEmpty3,10000);
timeit(isEmpty4,10000);


52
2017-12-28 09:58



Manière élégante - utiliser les touches

var myEmptyObj = {};
var myFullObj = {"key":"value"};
console.log(Object.keys(myEmptyObj).length); //0
console.log(Object.keys(myFullObj).length); //1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys


24
2018-01-07 00:10



function isEmpty( o ) {
    for ( var p in o ) { 
        if ( o.hasOwnProperty( p ) ) { return false; }
    }
    return true;
}

22
2018-02-14 15:56



Surpris de voir autant de réponses faibles sur une question aussi fondamentale de JS ...

  1. il génère une variable globale
  2. résultats true sur undefined
  3. les usages for...in ce qui est extrêmement lent en soi
  4. fonction à l'intérieur for...in est inutile - retour false sans pour autant hasOwnProperty la magie fonctionnera bien

En fait, il existe une solution plus simple:

function isEmpty(value){
    return Boolean(value && typeof value == 'object') && !Object.keys(value).length;
});

15
2017-10-21 12:21