3893 Stimmen

Wie kann ich auf ein leeres JavaScript-Objekt testen?

Nach einer AJAX-Anfrage kann es vorkommen, dass meine Anwendung ein leeres Objekt zurückgibt, z. B.:

var a = {};

Wie kann ich überprüfen, ob das der Fall ist?

7438voto

Adam Zerner Punkte 14785

ECMA 5+ :

// because Object.keys(new Date()).length === 0;
// we have to do some additional check
obj //  null and undefined check
&& Object.keys(obj).length === 0
&& Object.getPrototypeOf(obj) === Object.prototype

Beachten Sie jedoch, dass dies ein unnötiges Array erzeugt (der Rückgabewert von keys ).

Vor-ECMA 5:

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

  return JSON.stringify(obj) === JSON.stringify({});
}

jQuery :

jQuery.isEmptyObject({}); // true

lodash :

_.isEmpty({}); // true

Unterstrich :

_.isEmpty({}); // true

Hoek

Hoek.deepEqual({}, {}); // true

ExtJS

Ext.Object.isEmpty({}); // true

AngularJS (Version 1)

angular.equals({}, {}); // true

Ramda

R.isEmpty({}); // true

55 Stimmen

Object.keys(new Date()).length === 0 Diese Antwort kann also irreführend sein.

0 Stimmen

Warum müssen wir prüfen obj.contructor===Object in ECMA5+ Code ? Wir können nur diesen Code verwenden obj // null and undefined check && Object.keys(obj).length === 0

0 Stimmen

Der Kommentar direkt über Ihrem erklärt buchstäblich, warum =) Es gibt eine Million verschiedene Objekte, so dass Sie sicherstellen möchten, nur für "tatsächliche Objekt-Primitive" zu testen, d.h. Objekte, deren Konstruktor nicht eine Erweiterung von Object ist.

1374voto

Christoph Punkte 157217

Si ECMAScript 5-Unterstützung verfügbar ist, können Sie Object.keys() :

function isEmpty(obj) {
    return Object.keys(obj).length === 0;
}

Für ES3 und ältere Versionen gibt es keine einfache Möglichkeit, dies zu tun. Sie müssen explizit eine Schleife über die Eigenschaften ziehen:

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

    return true;
}

72 Stimmen

Das funktioniert gut, oder einfacher: function isEmpty(object) { for(var i in object) { return true; } return false; }

55 Stimmen

Sollten true und false in dieser Funktion nicht vertauscht werden?

47 Stimmen

@namtax: nein - die Funktion ist benannt isEmpty() also sollte es zurückgeben false wenn es eine Eigenschaft hat

591voto

Für diejenigen unter Ihnen, die das gleiche Problem haben, aber jQuery verwenden, können Sie jQuery.isEmptyObject .

3 Stimmen

Dies wird nicht funktionieren, wenn Sie (oder ein anderes Plugin) Object.prototype geändert haben.

1 Stimmen

Beachten Sie, dass dies funktioniert gut für die Frage gefragt, {}, aber dass jQuery.isEmptyObject([]) === true, vermutlich weil eine leere Liste ist iterable.

4 Stimmen

Beachten Sie, dass jQuery.isEmptyObject den Wert falsch wenn Sie es mit einem leeren jQuery-Objekt füttern (wie unter seine API-Seite ). Es funktioniert nur für normale JavaScript-Objekte.

384voto

Kamil Kiełczewski Punkte 69048

Leistung

Heute, 2020.01.17, habe ich Tests auf macOS High Sierra 10.13.6 mit Chrome v79.0, Safari v13.0.4 und Firefox v72.0 durchgeführt; für die gewählten Lösungen.

Schlussfolgerungen

  • Lösungen auf der Grundlage von for-in (A, J, L, M) sind am schnellsten
  • Lösungen auf der Grundlage von JSON.stringify (B, K) sind langsam
  • Überraschenderweise ist die Lösung, die auf Object (N) ist ebenfalls langsam

enter image description here

Detalles

Im folgenden Ausschnitt sind 15 Lösungen dargestellt. Wenn Sie einen Leistungstest auf Ihrem Rechner durchführen möchten, klicken Sie auf HIER . Dieser Link wurde 2021.07.08 aktualisiert, aber die Tests wurden ursprünglich durchgeführt ici - und die Ergebnisse in der obigen Tabelle stammen von dort (aber jetzt sieht es so aus, als ob dieser Dienst nicht mehr funktioniert).

var log = (s, f) => console.log(`${s} --> {}:${f({})}  {k:2}:${f({ k: 2 })}`);

function A(obj) {
  for (var i in obj) return false;
  return true;
}

function B(obj) {
  return JSON.stringify(obj) === "{}";
}

function C(obj) {
  return Object.keys(obj).length === 0;
}

function D(obj) {
  return Object.entries(obj).length === 0;
}

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

function F(obj) {
  return Object.keys(obj).length === 0 && obj.constructor === Object;
}

function G(obj) {
  return typeof obj === "undefined" || !Boolean(Object.keys(obj)[0]);
}

function H(obj) {
  return Object.entries(obj).length === 0 && obj.constructor === Object;
}

function I(obj) {
  return Object.values(obj).every((val) => typeof val === "undefined");
}

function J(obj) {
  for (const key in obj) {
    if (hasOwnProperty.call(obj, key)) {
      return false;
    }
  }
  return true;
}

function K(obj) {
  for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      return false;
    }
  }
  return JSON.stringify(obj) === JSON.stringify({});
}

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

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

function N(obj) {
  return (
    Object.getOwnPropertyNames(obj).length === 0 &&
    Object.getOwnPropertySymbols(obj).length === 0 &&
    Object.getPrototypeOf(obj) === Object.prototype
  );
}

function O(obj) {
  return !(Object.getOwnPropertyNames !== undefined
    ? Object.getOwnPropertyNames(obj).length !== 0
    : (function () {
        for (var key in obj) break;
        return key !== null && key !== undefined;
      })());
}

log("A", A);
log("B", B);
log("C", C);
log("D", D);
log("E", E);
log("F", F);
log("G", G);
log("H", H);
log("I", I);
log("J", J);
log("K", K);
log("L", L);
log("M", M);
log("N", N);
log("O", O);

enter image description here

0 Stimmen

Vieles davon macht keinen Sinn, weil du alles auf eine Rückgabe von falsch und oder wahr stützt. Manchmal braucht die Programmierung eine if-Anweisung oder einen ternären Operator. nur zur Info

15 Stimmen

Der Vollständigkeit halber habe ich Ihr jsperf bearbeitet, um zu testen obj = {a:1,b:2,c:3} y for(var i in obj) ist immer noch der schnellste jsperf.com/object-empty-ch/2

235voto

Baggz Punkte 16757

Sie können verwenden Underscore.js .

_.isEmpty({}); // true

32 Stimmen

Oder Sie könnten lodash is empty ( lodash.com/docs#isEmpty ), aber wie unterscheidet sich das von der Verwendung einer jQuery-Lösung - Sie müssen immer noch eine zusätzliche Bibliothek zu installieren. Ich denke, eine Vanilla-Javascript-Lösung ist die Absicht.

6 Stimmen

Wenn das Hinzufügen der gesamten Abhängigkeit für Ihre von der Leistung abhängige Anwendung belastend ist, können Sie nur _.isEmpty : npm i lodash.isempty

CodeJaeger.com

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.

Powered by:

X