Removing all properties from a object

I have this Javascript object.

req.session

In my code I add properties to this object. These properties can be other objects, arrays, or just plain strings.

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

If I later would like to erase all added properties of this object, what is the easiest/best way?

There must be a better way than this?

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

Solution 1:

@VisioN's answer works if you want to clear that specific reference, but if you actually want to clear an object I found that this works:

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

Solution 2:

There are two possible solutions to the problem:

Assign an empty object

req.session = {};

The garbage collector will clean the memory automatically. This variant is super fast and will work in most cases, however, you need to use it with caution, as it may keep the references to the objects in memory. This caveat is described in the TLDR section below.

Delete properties one-by-one

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

This will clean the object by going through every non-prototype property and deleting it. It's safer but slower. You need to decide if it makes sense for you to use it in a particular case.


TLDR

Any solution given above will do the job for the author in the current situation, as well as any other valid solution provided in this question. It mainly depends on the way how the developer wants to manipulate the deprecated data.

Session object may contain data that is linked by different variable, and setting a new empty object to req.session will not break the reference to the old data, so the old data will be available where it is still required. Although the correct way to keep old data is to clone the initial object, real-life scenarios can be different. Let's look at the following example:

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}

We still can fetch old data from session variable but req.session is empty: here setting a new object works as a sort of alternative to deep cloning. The garbage collector will not remove data from the old req.session object as it is still referenced by the session variable.

Deep cleaning of the object with:

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

... will explicitly remove all values from the req.session object and, since session variable is linked to the same object, session will become empty as well. Let's see how it works:

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 );       // {}, {}

As you can see now, in both cases we get empty objects.

From speed and memory perspectives setting a new empty object will be much faster than cleaning the old object property by property, however memory-wise if the old data is still referenced somewhere, the new object approach won't free up memory that old data is consuming.

It's quite obvious that choosing the approach to take is mostly up to your coding scenario but in most cases req.session = {}; will do the job: it is fast and short. However, if you keep references to the original object in other variables, you may consider using deep implicit object properties deletion.

Solution 3:

I can see only one correct solution for removing own properties from object:

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

If you want to use it more than once, you should create a cleaning function:

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

For your case the usage would be:

deleteProperties(req.session);

This solution removes properties from the object wherever it's referenced and keeping the old reference.
Example:
Using empty object assignment:

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

Using cleaning method:

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