我有这个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;
答案 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)
此脚本以递归方式移除属性,但向量中报告的数据除外。
- 功能:
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), {});