Entfernen aller Eigenschaften von einem Objekt

Lesezeit: 8 Minuten

Benutzer-Avatar
Anders Östmann

Ich habe dieses Javascript-Objekt.

req.session

In meinem Code füge ich diesem Objekt Eigenschaften hinzu. Diese Eigenschaften können andere Objekte, Arrays oder einfach nur Strings sein.

req.session.savedDoc = someObject; 
req.session.errors = ['someThing', 'anotherThing', 'thirdThing'];
req.session.message="someString"

Wenn ich später alle hinzugefügten Eigenschaften dieses Objekts löschen möchte, was ist der einfachste/beste Weg?

Es muss einen besseren Weg als diesen geben?

// Delete all session values
delete req.session.savedDoc;
delete req.session.errors;
delete req.session.message;

  • Siehe auch Leistungsvergleich: Leistung – Wie lösche ich schnell ein JavaScript-Objekt? – Paketüberfluss

    – Benutzer202729

    24. Dezember 2021 um 11:16 Uhr

Die Antwort von @VisioN funktioniert, wenn Sie diese bestimmte Referenz löschen möchten, aber wenn Sie tatsächlich ein Objekt löschen möchten, habe ich festgestellt, dass dies funktioniert:

for (var variableKey in vartoClear){
    if (vartoClear.hasOwnProperty(variableKey)){
        delete vartoClear[variableKey];
    }
}

  • Warum hat diese Antwort nicht mehr Upvotes … Dadurch wird das Objekt tatsächlich gelöscht, anstatt ein neues Objekt zu erstellen (alte Daten sind noch vorhanden, wenn auf das alte Objekt von etwas verwiesen wird).

    – basisch6

    3. Mai 2015 um 20:06 Uhr

  • Ja! Was @basic6 gesagt hat. Ich bin heute auf dieses Problem gestoßen, bei dem das Erstellen eines neuen Objekts eine andere Referenz, die ich hatte, unterbrach. Dies sollte die richtige Antwort sein.

    – James Manes

    7. Juli 2016 um 15:37 Uhr

  • Besteht die Gefahr, dass einige JavaScript-Implementierungen verwirrt werden, wenn es darum geht, eine Eigenschaft zu löschen, während sie Eigenschaften aufzählt? Oder gibt die Definition der “in”-Enumeration genau an, was passieren soll, wenn Eigenschaften während der Enumeration hinzugefügt und entfernt werden?

    – Adam Gawne-Cain

    31. Dezember 2020 um 10:48 Uhr

  • @AdamGawne-Cain Es sollte keine solche Gefahr geben. Der Abschnitt 12.6.4 des ECMAScript 5.1-Standards (zu for-in-Schleifen) sagt: “Eigenschaften des aufzuzählenden Objekts können während der Aufzählung gelöscht werden.”

    – Juan Mendes

    31. März um 19:26 Uhr


Benutzer-Avatar
Vision

Es gibt zwei mögliche Lösungen für das Problem:

Weisen Sie ein leeres Objekt zu

req.session = {};

Der Garbage Collector bereinigt den Speicher automatisch. Diese Variante ist superschnell und funktioniert in den meisten Fällen, allerdings müssen Sie sie mit verwenden Vorsicht, da es die Verweise auf die Objekte im Speicher behalten kann. Dieser Vorbehalt ist in der beschrieben TLDR Abschnitt unten.

Eigenschaften einzeln löschen

Object.keys(object).forEach(key => delete object[key]);

Dadurch wird das Objekt bereinigt, indem alle Nicht-Prototyp-Eigenschaften durchlaufen und gelöscht werden. Es ist sicherer, aber langsamer. Sie müssen entscheiden, ob es für Sie sinnvoll ist, es in einem bestimmten Fall zu verwenden.


TLDR

Jede oben angegebene Lösung wird für den Autor in der aktuellen Situation die Arbeit erledigen, ebenso wie jede andere gültige Lösung, die in dieser Frage bereitgestellt wird. Es hängt hauptsächlich davon ab, wie der Entwickler die veralteten Daten manipulieren möchte.

Das Sitzungsobjekt kann Daten enthalten, die durch verschiedene Variablen verknüpft sind, und ein neues leeres Objekt festlegen req.session wird den Verweis auf die alten Daten nicht aufheben, sodass die alten Daten dort verfügbar sind, wo sie noch benötigt werden. Obwohl der richtige Weg, alte Daten aufzubewahren, darin besteht, das ursprüngliche Objekt zu klonen, können reale Szenarien anders aussehen. Schauen wir uns das folgende Beispiel an:

req.session.user = { name: "Alexander" };  // we store an object in the session
var session = req.session;                 // save reference to the session in a variable
console.log( req.session, session );       // {user: Object}, {user: Object}

req.session = {};                          // let's replace session with a new object
console.log( req.session, session );       // {}, {user: Object}

Wir können immer noch alte Daten von abrufen session variabel aber req.session ist leer: Hier funktioniert das Setzen eines neuen Objekts als eine Art Alternative zum Deep Cloning. Der Garbage Collector entfernt keine Daten aus dem alten req.session Objekt, da es immer noch von der referenziert wird session Variable.

Tiefenreinigung des Objekts mit:

Object.keys(object).forEach(key => delete object[key]);

… Wille ausdrücklich Entfernen Sie alle Werte aus der req.session Objekt und seit session Variable ist mit demselben Objekt verknüpft, session wird auch leer. Mal sehen, wie es funktioniert:

req.session.user = { name: "Alexander" };  // we store an object in the session
var session = req.session;                 // save reference to the session in a variable
console.log( req.session, session );       // {user: Object}, {user: Object}

Object.keys(req.session).forEach(key => delete req.session[key]);
console.log( req.session, session );       // {}, {}

Wie Sie jetzt sehen können, erhalten wir in beiden Fällen leere Objekte.

Aus Geschwindigkeits- und Speicherperspektive wird ein neues leeres Objekt gesetzt viel schneller als das alte Objekt Eigenschaft für Eigenschaft zu bereinigen, jedoch wird der neue Objektansatz keinen Speicher freigeben, den alte Daten verbrauchen, wenn auf die alten Daten noch irgendwo verwiesen wird.

Es ist ziemlich offensichtlich, dass die Wahl des Ansatzes hauptsächlich von Ihrem Codierungsszenario abhängt, aber in den meisten Fällen req.session = {}; wird die Arbeit erledigen: Es ist schnell und kurz. Wenn Sie jedoch Verweise auf das ursprüngliche Objekt in anderen Variablen beibehalten, können Sie erwägen, die tiefe implizite Löschung von Objekteigenschaften zu verwenden.

  • Ich frage mich, ob es besser ist, req.session = null oder req.session = {} zu verwenden. Die Express-Site schlägt vor, sie auf null zu setzen expressjs.com/api.html#cookieSession

    – Sriharsha

    11. Oktober 2013 um 11:40 Uhr

  • Dies ist eine nützliche Antwort, aber ich glaube nicht, dass sie vollständig ist, da sie nicht alle Eigenschaften von einem Objekt entfernt. Wenn Sie 2 Verweise auf dasselbe Objekt haben, req.session1 und req.session2, und weisen Sie req.session1 = {} zu. Dann bleibt req.session2 gleich, wobei alle seine Eigenschaften noch definiert sind

    – Das Ö

    19. Februar 2014 um 11:57 Uhr

  • Obwohl das Ergebnis ein leeres Objekt ist, verweist das Objekt jetzt auf einen neuen Punkt im Speicher – dh ein neues Objekt. Das heißt, wenn es einen doppelten Verweis auf dieses Objekt gab, ist es jetzt weg. Fazit: Das Objekt wird nicht geleert, sondern durch ein neues ersetzt.

    – Tomer

    16. April 2014 um 12:50 Uhr

  • Dies beantwortet nicht die Frage des OP.

    – Peter Alvin

    7. Dezember 2014 um 17:29 Uhr


  • Er denkt, es sollte ein leeres Objekt drucken, weil die Frage genau danach fragt. Sobald Sie alle Eigenschaften von einem Objekt entfernt haben, haben Sie ein leeres Objekt.

    – David Lugg

    30. Juni 2015 um 4:46 Uhr

Benutzer-Avatar
icl7126

Ich sehe nur eine richtige Lösung zum Entfernen eigener Eigenschaften vom Objekt:

for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];

Wenn Sie es mehr als einmal verwenden möchten, sollten Sie eine Reinigungsfunktion erstellen:

function deleteProperties(objectToClean) {
  for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];
}

Für Ihren Fall wäre die Verwendung:

deleteProperties(req.session);

Diese Lösung entfernt Eigenschaften aus dem Objekt, wo immer es referenziert wird, und behält die alte Referenz bei.
Beispiel:
Leere Objektzuweisung verwenden:

var x = {a: 5};
var y = x;
x = {};    // x will be empty but y is still {a: 5}, also now reference is gone: x !== y

Verwendung der Reinigungsmethode:

var x = {a: 5};
var y = x;
deleteProperties(x);  // x and y are both empty and x === y

Wenn Sie alle Eigenschaften löschen möchten, ohne Methoden zu berühren, können Sie Folgendes verwenden:

for(var k in req.session) if(!req.session[k].constructor.toString().match(/^function Function\(/)) delete req.session[k];

Benutzer-Avatar
EnTr0cKs

Ich habe es so gemacht

var 
    i,
    keys = Object.keys(obj);
for(i = 0; i < keys.length; i++){
    delete obj[keys[i]];
}

Sie könnten es zu Objekt hinzufügen (Prototyp ist hier nicht ideal) – wird statisch sein.

Object.defineproperties(Object, {
    'clear': function(target){
        var 
            i,
            keys = Object.keys(target);
        for(i = 0; i < keys.length; i++){
            delete target[keys[i]];
        }
    }
});

Dann können Sie zufällige Objekte mit löschen

Object.clear(yourObj);

yourObj = {} ersetzt den Verweis auf ein neues Objekt, das obige entfernt seine Eigenschaften – der Verweis ist derselbe.

  • Ich möchte hinzufügen, dass dies etwas kostspielige Operationen sind – Umstrukturierungen, und dass es wahrscheinlich bessere Wege gibt, um seine Ziele zu erreichen.

    – EnTr0cKs

    19. Februar 2017 um 17:30 Uhr

Das Naive object = {} -Methode ist für Vanilla Object in Ordnung, löscht jedoch Prototypen von benutzerdefinierten Objekten.

Diese Methode erzeugt ein leeres Objekt, das bewahrt Prototypenverwenden Object.getPrototypeOf() und Objekt.erstellen():

    emptyObj = Object.create(Object.getPrototypeOf(obj), {});

Beispiel:

class Custom extends Object {
  custom() {}
}

let custom = new Custom();
custom.foo = "bar";
console.log(custom.constructor.name, custom);
// Custom {"foo": "bar"}

// naive method:
let objVanilla = {}
console.log(objVanilla.constructor.name, objVanilla);
// Object {}

// safe method:
objSafe = Object.create(Object.getPrototypeOf(custom), {});
console.log(objSafe.constructor.name, objSafe);
// Custom {}

  • Ich möchte hinzufügen, dass dies etwas kostspielige Operationen sind – Umstrukturierungen, und dass es wahrscheinlich bessere Wege gibt, um seine Ziele zu erreichen.

    – EnTr0cKs

    19. Februar 2017 um 17:30 Uhr

Dieses Skript entfernt Eigenschaften rekursiv mit Ausnahme der in Vektor gemeldeten Daten.

Du brauchst die Lodash-Bibliothek

— Funktion:

function removeKeysExcept(object, keysExcept = [], isFirstLevel = true) {
        let arrayKeysExcept = [],
            arrayNextKeysExcept = {};
        _.forEach(keysExcept, (value, i) => {
            let j = value.split('.');
            let keyExcept = j[0];
            arrayKeysExcept.push(keyExcept);
            j.shift();
            if (j.length) {
                j = j.join('.');
                if (!arrayNextKeysExcept[keyExcept]) {
                    arrayNextKeysExcept[keyExcept] = [];
                }
                arrayNextKeysExcept[keyExcept].push(j);
            }
        })
        _.forEach(arrayNextKeysExcept, (value, key) => {
            removeKeysExcept(object[key], value, false);
        });
        if (isFirstLevel) {
            return;
        }
        Object.keys(object).forEach(function (key) {
            if (arrayKeysExcept.indexOf(key) == -1) {
                delete object[key];
            }
        });
    }

So laufen:

— Entfernt alle Eigenschaften außer der ersten Ebene und im Vektor gemeldet:

removeKeysExcept(obj, ['department.id','user.id']);

— Entfernt alle Eigenschaften

removeKeysExcept(obj, ['department.id','user.id'], false);

— Beispiel:

let obj = {
    a: {
        aa: 1,
        ab: {
            aba: 21
        }
    },
    b: 10,
    c: {
        ca: 100,
        cb: 200
    }
};

removeKeysExcept(obj, ['a.ab.aba','c.ca']);
/*OUTPUT: {
    a: {
        ab: {
            aba: 21
        }
    },
    b: 10,
    c: {
        ca: 100,
    }
};*/

removeKeysExcept(obj, ['a.ab.aba','c.ca'], false); //Remove too firt level
/*OUTPUT: {
    a: {
        ab: {
            aba: 21
        }
    },
    c: {
        ca: 100,
    }
};*/

removeKeysExcept(obj);
/*OUTPUT: {b:10};*/

removeKeysExcept(obj, [], false); //Remove too firt level
/*OUTPUT: {};*/

1176120cookie-checkEntfernen aller Eigenschaften von einem Objekt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy