Wie kann man am schnellsten prüfen, ob ein Objekt leer ist oder nicht?
Gibt es einen schnelleren und besseren Weg als diesen?
function count_obj(obj){
var i = 0;
for(var key in obj){
++i;
}
return i;
}
Wie kann man am schnellsten prüfen, ob ein Objekt leer ist oder nicht?
Gibt es einen schnelleren und besseren Weg als diesen?
function count_obj(obj){
var i = 0;
for(var key in obj){
++i;
}
return i;
}
Eine angemessenere ES5-Lösung wäre Object.getOwnPropertyNames(obj).length == 0
というのも Object.keys
erhält nur die aufzählbar Eigenschaften. In ES5 haben wir die Möglichkeit, Eigenschaftsattribute zu definieren, wir könnten ein Objekt mit nicht aufzählbaren Eigenschaften haben und Object.keys
wird einfach ein leeres Array zurückgeben... Object.getOwnPropertyNames
gibt ein Array zurück, das todos die eigenen Eigenschaften eines Objekts, auch wenn sie nicht aufzählbar sind.
@CMS getOwnPropertyNames
es empfohlen von Crockford . Ihm zufolge wurde diese Methode speziell für Caja (und andere sichere Frameworks, nehme ich an) in die Sprache eingeführt. Es besteht also die Möglichkeit, dass diese Methode in bestimmten Umgebungen nicht verfügbar ist oder sein wird.
Ich gehe davon aus, dass durch leer Sie meinen "hat keine eigenen Eigenschaften".
// 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;
}
Beispiele:
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
Wenn Sie nur Folgendes bearbeiten müssen ECMAScript5-Browser können Sie verwenden Object.getOwnPropertyNames
anstelle der hasOwnProperty
Schleife:
if (Object.getOwnPropertyNames(obj).length > 0) return false;
Dadurch wird sichergestellt, dass selbst wenn das Objekt nur nicht aufzählbare Eigenschaften hat isEmpty
erhalten Sie trotzdem die richtigen Ergebnisse.
@SeanVieira is_empty({length: 0, custom_property: []}) gibt false zurück. Ich bin mir nicht sicher, wie der Code funktionieren soll, aber ich würde erwarten, dass er korrekt ist, wenn Sie Folgendes hinzufügen: if (obj.length === 0) return true; after if (obj.length && obj.length > 0) return false; es wäre korrekt
@pgreen2 - gut gefangen! Ich habe das Beispiel aktualisiert, um eine explizite Prüfung auf 0 einzuschließen - danke für die Hilfe bei der Verbesserung der Antwort!
JSLint beschwert sich hasOwnProperty is a really bad name
. Das behebt es {}.hasOwnProperty.call(obj, key)
. Impressum ici
EDIT : Beachten Sie, dass Sie wahrscheinlich ES5-Lösung stattdessen, da die ES5-Unterstützung weit verbreitet in diesen Tagen. Es funktioniert immer noch für jQuery aber.
Ein einfacher und browserübergreifender Weg ist die Verwendung von jQuery.isEmptyObject
:
if ($.isEmptyObject(obj))
{
// do something
}
Mehr: http://api.jquery.com/jQuery.isEmptyObject/
Sie benötigen jedoch Jquery.
Ich finde es amüsant, dass die jQuery-Option diejenige ist, die "vorbildlich und einer zusätzlichen Prämie würdig" ist, über eine native ES5-Lösung . Diese Antwort ist in einigen Fällen immer noch nützlich, nehme ich an.
Die ES5-Lösung wird (noch) nicht von allen Browsern unterstützt (zumindest AFAIK), daher ist diese Lösung sinnvoll, wenn Sie bereits jQuery verwenden (was bei vielen Websites der Fall ist). Außerdem ist jQuery ein bisschen effizienter als Jakobs Lösung (nicht, dass es in den meisten Fällen viel ausmacht), da es nicht das ganze Objekt durchläuft, bevor es die Länge berechnet - es gibt false, sobald ein Schlüssel gefunden wird .
Unterstrich y lodash haben jeweils eine praktische isEmpty()
Funktion, wenn es Ihnen nichts ausmacht, eine zusätzliche Bibliothek hinzuzufügen.
_.isEmpty({});
Späte Bemerkung: für 2016 können Sie nur lodash verwenden isEmpty (Sie müssen nicht die gesamte Lodash importieren, Sie können jetzt nur eine Methode daraus importieren, sie wurde in mehrere Mikropakete in npm aufgeteilt).
Ja, oder Sie könnten importieren node_modules/*
und ignorieren Sie jede Abhängigkeit von einem Plugin </sarcasm>
Lassen Sie uns dieses Baby zu Bett; getestet unter Node, Chrome, Firefox und IE 9, wird es offensichtlich, dass für die meisten Anwendungsfälle:
Unterm Strich Leistung, verwenden:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
o
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
Ergebnisse unter Node:
return (Object.keys(obj).length === 0)
for (var x in obj) { return false; }...
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
return ('{}' === JSON.stringify(obj))
Prüfung auf Objekt mit 0 Schlüsseln 0.00018 0.000015 0.000015 0.000324
Prüfung auf Objekt mit 1 Schlüssel 0.000346 0.000458 0.000577 0.000657
Prüfung auf Objekt mit 2 Schlüsseln 0.000375 0.00046 0.000565 0.000773
Prüfung auf Objekt mit 3 Schlüsseln 0.000406 0.000476 0.000577 0.000904
Prüfung auf Objekt mit 4 Tasten 0.000435 0.000487 0.000589 0.001031
Prüfung auf Objekt mit 5 Schlüsseln 0.000465 0.000501 0.000604 0.001148
Prüfung auf Objekt mit 6 Tasten 0.000492 0.000511 0.000618 0.001269
Prüfung auf Objekt mit 7 Tasten 0.000528 0.000527 0.000637 0.00138
Prüfung auf Objekt mit 8 Tasten 0.000565 0.000538 0.000647 0.00159
Prüfung auf Objekt mit 100 Schlüsseln 0.003718 0.00243 0.002535 0.01381
Testen auf Objekt mit 1000 Schlüsseln 0.0337 0.0193 0.0194 0.1337
Wenn Ihr typischer Anwendungsfall ein nicht leeres Objekt mit wenigen Schlüsseln testet und Sie selten leere Objekte oder Objekte mit 10 oder mehr Schlüsseln testen, sollten Sie die Option Object.keys(obj).length in Betracht ziehen. - Andernfalls sollten Sie die allgemeinere (for... in...) Implementierung verwenden.
Beachten Sie, dass Firefox scheinen eine schnellere Unterstützung für Object.keys(obj).length und Object.getOwnPropertyNames(obj).length, so dass es eine bessere Wahl für jede nicht leere Objekt, aber immer noch, wenn es darum geht, leere Objekte, die (for...in...) ist einfach 10 mal schneller.
Meine 2 Cents ist, dass Object.keys(obj).length eine schlechte Idee ist, da es ein Objekt von Schlüsseln erstellt, nur um zu zählen, wie viele Schlüssel darin sind, dann zerstört es! Um dieses Objekt zu erstellen, muss er die Schlüssel in einer Schleife durchlaufen... warum also diese und nicht die Option (for... in...) verwenden :)
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);
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
6 Stimmen
Möchten Sie die Eigenschaften zählen (das ist es, was der Code tut) oder nur testen, ob das Objekt leer ist oder nicht (das ist in Ihrer Frage angegeben)?
2 Stimmen
Nur als Empfehlung von Bibliotheken, die dazu in der Lage sind is.js y lodash
0 Stimmen
Für derartige Dienstprogramme empfiehlt es sich, einige Bibliotheken zu verwenden. Sie könnten lodash verwenden und etwas wie
_.isEmpty(_.keys(yourObject))
. Und ich glaube, Sie können jetzt diese beiden Methoden einzeln importieren, und nicht die gesamte Lodash-Bibliothek.