109 votes

Suppression de toutes les propriétés d'un objet

J'ai cet objet Javascript.

req.session

Dans mon code, j'ajoute des propriétés à cet objet. Ces propriétés peuvent être d'autres objets, des tableaux, ou simplement des chaînes de caractères.

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

Si je veux ensuite effacer toutes les propriétés ajoutées à cet objet, quelle est la manière la plus simple/meilleure ?

Il doit y avoir une meilleure manière que celle-ci ?

// Supprimer toutes les valeurs de session
delete req.session.savedDoc;
delete req.session.errors;
delete req.session.message;

167voto

Dave Lugg Points 109

La réponse de @VisioN fonctionne si vous voulez effacer cette référence spécifique, mais si vous voulez effectivement effacer un objet j'ai trouvé que cela fonctionne :

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

97voto

VisioN Points 62518

Il existe deux solutions possibles au problème :

Assigner un objet vide

req.session = {};

Le ramasse-miettes nettoiera automatiquement la mémoire. Cette variante est très rapide et fonctionnera dans la plupart des cas, cependant, vous devez l'utiliser avec précaution, car elle peut conserver les références aux objets en mémoire. Cette mise en garde est décrite dans la section TLDR ci-dessous.

Supprimer les propriétés une par une

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

Cela nettoiera l'objet en parcourant chaque propriété non-prototype et en la supprimant. C'est plus sûr mais plus lent. Vous devez décider s'il est pertinent de l'utiliser dans un cas particulier.


TLDR

Toute solution donnée ci-dessus fera l'affaire pour l'auteur dans la situation actuelle, ainsi que toute autre solution valide fournie dans cette question. Cela dépend principalement de la manière dont le développeur souhaite manipuler les données obsolètes.

L'objet de session peut contenir des données qui sont liées par différentes variables, et le fait de définir un nouvel objet vide pour req.session ne rompra pas la référence aux anciennes données, de sorte que les anciennes données seront disponibles là où elles sont encore nécessaires. Bien que la bonne manière de conserver les anciennes données soit de cloner l'objet initial, les scénarios réels peuvent être différents. Regardons l'exemple suivant :

req.session.user = { name: "Alexander" };  // nous stockons un objet dans la session
var session = req.session;                 // sauvegarder la référence à la session dans une variable
console.log( req.session, session );       // {user: Object}, {user: Object}

req.session = {};                          // remplaçons la session par un nouvel objet
console.log( req.session, session );       // {}, {user: Object}

Nous pouvons toujours récupérer les anciennes données de la variable session mais req.session est vide : ici, le fait de définir un nouvel objet fonctionne comme une sorte de clonage profond. Le ramasse-miettes ne supprimera pas les données de l'ancien objet req.session car il est toujours référencé par la variable session.

Un nettoyage profond de l'objet avec :

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

... supprimera explicitement toutes les valeurs de l'objet req.session et, comme la variable session est liée au même objet, session deviendra également vide. Voyons comment cela fonctionne :

req.session.user = { name: "Alexander" };  // nous stockons un objet dans la session
var session = req.session;                 // sauvegarder la référence à la session dans une 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 );       // {}, {}

Comme vous pouvez le voir maintenant, dans les deux cas nous obtenons des objets vides.

D'un point de vue de la vitesse et de la mémoire, définir un nouvel objet vide sera beaucoup plus rapide que nettoyer l'ancien objet propriété par propriété, cependant, du point de vue de la mémoire, si les anciennes données sont encore référencées quelque part, l'approche avec le nouvel objet ne libérera pas la mémoire que les anciennes données consomment.

Il est assez évident que le choix de l'approche à adopter dépend principalement de votre scénario de codage, mais dans la plupart des cas req.session = {}; fera l'affaire : c'est rapide et court. Cependant, si vous conservez des références à l'objet d'origine dans d'autres variables, vous pouvez envisager d'utiliser la suppression implicite des propriétés d'objet en profondeur.

14voto

klerik Points 385

Je ne peux voir qu'une seule solution correcte pour supprimer ses propres propriétés d'un objet :

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

Si vous souhaitez l'utiliser plusieurs fois, vous devriez créer une fonction de nettoyage :

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

Pour votre cas, l'utilisation serait :

deleteProperties(req.session);

Cette solution supprime les propriétés de l'objet où qu'elles soient référencées et conserve l'ancienne référence.
Exemple :
En utilisant l'assignation d'un objet vide :

var x = {a: 5};
var y = x;
x = {};    // x sera vide mais y est toujours {a: 5}, la référence est également perdue : x !== y

En utilisant la méthode de nettoyage :

var x = {a: 5};
var y = x;
deleteProperties(x);  // x et y sont tous deux vides et x === y

6voto

yent Points 1243

Si vous voulez supprimer toutes les propriétés sans toucher aux méthodes, vous pouvez utiliser :

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

5voto

Gabriel Petersson Points 2009

Vous pouvez utiliser une carte à la place si vous vous souciez des performances comme ceci

const map = new Map()
map.set("first", 1)
map.set("second", 1)
map.clear()

C'est une opération O(1), donc même si vous avez un objet énorme, vous n'avez pas besoin d'itérer x fois pour supprimer les entrées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X