从对象中删除所有属性

时间:2013-10-11 11:19:21

标签: javascript node.js

我有这个Javascript对象。

req.session

在我的代码中,我向此对象添加属性。这些属性可以是其他对象,数组或纯字符串。

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

如果我以后想要删除此对象的所有添加属性,最简单/最好的方法是什么?

必须有比这更好的方法吗?

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

7 个答案:

答案 0 :(得分:107)

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

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

答案 1 :(得分:41)

只需指定一个空对象:

req.session = {};

......垃圾收集器将自动完成剩下的工作。


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

上面给出的解决方案将在当前情况下为作者完成工作,以及此问题中提供的任何其他有效解决方案。它主要取决于开发人员如何操纵已弃用的数据。

会话对象可能包含由不同变量链接的数据,并且将新的空对象设置为req.session不会破坏对旧数据的引用,因此旧数据将在仍需要的地方可用。虽然保留旧数据的正确方法是克隆初始对象,但现实生活场景可能会有所不同。我们来看下面的例子:

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}

我们仍然可以从session变量中获取旧数据,但req.session为空:此处设置新对象可作为深度克隆的替代方法。垃圾收集器不会从旧req.session对象中删除数据,因为它仍由session变量引用。

使用@Dave提供的方法或通过Object.keys更短的方式深度清理对象(忽略原型链中的属性,并且 node.js ):

Object.keys(object).forEach(function(key) { delete object[key]; });

...将显式删除req.session对象中的所有值,并且由于session变量链接到同一对象,session将变为空同样。让我们看看它是如何工作的:

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

正如您现在所看到的,在这两种情况下我们都会获得空对象。

从速度和内存的角度来看,设置新的空对象比按属性清除旧的对象属性要快得多,但是如果旧的数据仍在某处被引用,那么新的对象方法将赢得'释放旧数据正在消耗的内存。

很明显,选择采用的方法主要取决于您的编码方案,但在大多数情况下req.session = {};将完成工作:它快速而短暂。但是,如果在其他变量中保留对原始对象的引用,则可以考虑使用深度隐式对象属性删除。

答案 2 :(得分:10)

我只能看到一个正确的解决方案,用于从对象中删除自己的属性:

$e = explode("Company:", $string);

如果您想多次使用它,您应该创建一个清洁功能:

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

对于您的情况,用法是:

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

此解决方案从对象的任何位置删除属性,并保留旧引用 示例:
使用空对象分配:

deleteProperties(req.session);

使用清洁方法:

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

答案 3 :(得分:6)

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

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

答案 4 :(得分:1)

我这样做了

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

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

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

然后你可以用

清除随机对象
Object.clear(yourObj);

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

答案 5 :(得分:0)

此脚本以递归方式移除属性,但向量中报告的数据除外。

您需要lodash library

- 功能:

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

运行:

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

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

- 删除所有属性

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

- 输出:

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

答案 6 :(得分:0)

天真的strcmp()方法对于普通对象是可以的,但是会删除自定义对象的原型。

此方法使用Object.getPrototypeOf()Object.create()生成一个空对象,该对象保留原型

object = {}

示例:

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