从对象中删除所有属性。

时间:2022-09-25 10:23:47

I have this Javascript object.

我有这个Javascript对象。

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;

6 个解决方案

#1


31  

Simply assign an empty object:

简单地分配一个空对象:

req.session = {};

... and the garbage collector will do the rest automatically.

…垃圾收集器将自动执行其余操作。


UPDATE: Since this answer is disputable, I would like to provide some more details on the point.

更新:由于这个答案是有争议的,我想提供更多关于这一点的细节。

The 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。会话不会中断对旧数据的引用,因此旧数据将在仍然需要的地方可用。尽管保存旧数据的正确方法是克隆初始对象,但现实生活中的场景可能有所不同。让我们看看下面的例子:

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 sort of alternative to deep cloning. The garbage collector will not remove data from old req.session object as it is still referenced by session variable.

我们仍然可以从会话变量req中获取旧数据。会话为空:在这里,设置一个新对象作为深度克隆的一种替代。垃圾收集器不会从旧的req中删除数据。会话对象,因为它仍然被会话变量引用。

Deep cleaning of the object with method provided by @Dave or shorter via Object.keys (which ignores properties in the prototype chain and doesn't require any shims for node.js):

用@Dave或通过object提供的方法对对象进行深度清洗。键(忽略原型链中的属性,node.js不需要任何垫片):

Object.keys(object).forEach(function(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中删除所有值。会话对象和,由于会话变量链接到同一个对象,会话也将变为空。让我们看看它是如何工作的:

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(function(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 new empty object will be much faster than cleaning the old object property by property, however memory-wise if 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.

很明显,选择要采用的方法主要取决于您的编码场景,但在大多数情况下是req。会话= { };会做这项工作:它又快又短。但是,如果您在其他变量中保留对原始对象的引用,您可以考虑使用深层隐式对象属性删除。

#2


90  

@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:

@VisioN的答案可以,如果你想要清除特定的引用,但是如果你想要清除一个我发现有效的对象:

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

#3


10  

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

#4


5  

If you want to delete all properties without touching methods you can use :

如果你想删除所有属性而不触及方法,你可以使用:

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

#5


1  

I've done it like this

我是这样做的

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

You could add it to Object (prototype's not ideal here) - will be static.

你可以把它添加到对象(原型在这里不理想)-将是静态的。

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

Then you can clear random objects with

然后你可以清除随机对象。

Object.clear(yourObj);

yourObj = {} replaces the reference to a new object, the above removes it's properties - reference is the same.

yourObj ={}替换对新对象的引用,上面的操作删除了它的属性——引用是相同的。

#6


0  

This script removes property recursively except for the data reported in vector.

这个脚本递归地删除属性,除了向量中报告的数据。

You need the lodash library

你需要lodash库

-- Function:

——功能:

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];
            }
        });
    }

Run so:

所以运行:

-- Removes all properties except the first level and reported in the vector:

-删除除第一级以外的所有属性,并在vector中报告:

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

-- Removes all properties

——删除所有属性

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

-- OUTPUT:

——输出:

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: {};*/

#1


31  

Simply assign an empty object:

简单地分配一个空对象:

req.session = {};

... and the garbage collector will do the rest automatically.

…垃圾收集器将自动执行其余操作。


UPDATE: Since this answer is disputable, I would like to provide some more details on the point.

更新:由于这个答案是有争议的,我想提供更多关于这一点的细节。

The 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。会话不会中断对旧数据的引用,因此旧数据将在仍然需要的地方可用。尽管保存旧数据的正确方法是克隆初始对象,但现实生活中的场景可能有所不同。让我们看看下面的例子:

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 sort of alternative to deep cloning. The garbage collector will not remove data from old req.session object as it is still referenced by session variable.

我们仍然可以从会话变量req中获取旧数据。会话为空:在这里,设置一个新对象作为深度克隆的一种替代。垃圾收集器不会从旧的req中删除数据。会话对象,因为它仍然被会话变量引用。

Deep cleaning of the object with method provided by @Dave or shorter via Object.keys (which ignores properties in the prototype chain and doesn't require any shims for node.js):

用@Dave或通过object提供的方法对对象进行深度清洗。键(忽略原型链中的属性,node.js不需要任何垫片):

Object.keys(object).forEach(function(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中删除所有值。会话对象和,由于会话变量链接到同一个对象,会话也将变为空。让我们看看它是如何工作的:

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(function(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 new empty object will be much faster than cleaning the old object property by property, however memory-wise if 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.

很明显,选择要采用的方法主要取决于您的编码场景,但在大多数情况下是req。会话= { };会做这项工作:它又快又短。但是,如果您在其他变量中保留对原始对象的引用,您可以考虑使用深层隐式对象属性删除。

#2


90  

@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:

@VisioN的答案可以,如果你想要清除特定的引用,但是如果你想要清除一个我发现有效的对象:

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

#3


10  

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

#4


5  

If you want to delete all properties without touching methods you can use :

如果你想删除所有属性而不触及方法,你可以使用:

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

#5


1  

I've done it like this

我是这样做的

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

You could add it to Object (prototype's not ideal here) - will be static.

你可以把它添加到对象(原型在这里不理想)-将是静态的。

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

Then you can clear random objects with

然后你可以清除随机对象。

Object.clear(yourObj);

yourObj = {} replaces the reference to a new object, the above removes it's properties - reference is the same.

yourObj ={}替换对新对象的引用,上面的操作删除了它的属性——引用是相同的。

#6


0  

This script removes property recursively except for the data reported in vector.

这个脚本递归地删除属性,除了向量中报告的数据。

You need the lodash library

你需要lodash库

-- Function:

——功能:

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];
            }
        });
    }

Run so:

所以运行:

-- Removes all properties except the first level and reported in the vector:

-删除除第一级以外的所有属性,并在vector中报告:

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

-- Removes all properties

——删除所有属性

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

-- OUTPUT:

——输出:

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: {};*/