简体   繁体   English

从 object 中删除所有属性

[英]Removing all properties from a object

I have this Javascript object.我有这个 Javascript object。

req.session

In my code I add properties to this object.在我的代码中,我向这个 object 添加了属性。 These properties can be other objects, arrays, or just plain strings.这些属性可以是其他对象,arrays,或者只是简单的字符串。

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?如果我以后想删除这个 object 的所有添加属性,最简单/最好的方法是什么?

There must be a better way than this?一定有比这更好的方法吗?

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

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

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. Session 对象可能包含由不同变量链接的数据,将新的空对象设置为req.session不会破坏对旧数据的引用,因此旧数据将在仍然需要的地方可用。 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 sort of alternative to deep cloning.我们仍然可以从session变量中获取旧数据,但req.session是空的:这里设置一个新对象可以作为深度克隆的替代方法。 The garbage collector will not remove data from old req.session object as it is still referenced by session variable.垃圾收集器不会从旧的req.session对象中删除数据,因为它仍然被session变量引用。

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.keys更短的方法深度清理对象(忽略原型链中的属性并且不需要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. ...将从req.session对象中明确删除所有值,并且由于session变量链接到同一个对象, session也将变为空。 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(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 = {};很明显,选择采用的方法主要取决于您的编码场景,但在大多数情况下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.但是,如果在其他变量中保留对原始对象的引用,则可以考虑使用深层隐式对象属性删除。

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

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

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

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 (原型在这里并不理想) - 将是静态的。

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 = {}替换对新对象的引用,上面删除了它的属性 - 引用是相同的。

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: -- 删除除第一级之外的所有属性并在向量中报告:

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

-- Removes all properties -- 删除所有属性

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

-- Example: -- 例子:

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

The naive object = {} method is okay for vanilla Object, but it deletes prototypes of custom objects. naive object = {}方法适用于 vanilla Object,但它删除了自定义对象的原型。

This method produces an empty object that preserves prototypes , using Object.getPrototypeOf() and Object.create() :此方法使用Object.getPrototypeOf()Object.create()生成一个保留原型的空对象:

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

Example:示例:

 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 {}

You can use a map instead if you care about performance like so如果您关心这样的性能,您可以使用 map

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

This is a O(1) operation, so even if you have a huge object you do not need to iterate x times to delete the entries.这是一个O(1)操作,所以即使你有一个巨大的 object 你也不需要迭代 x 次来删除条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM