从对象中删除所有属性

And*_*man 61 javascript node.js

我有这个Javascript对象.

req.session
Run Code Online (Sandbox Code Playgroud)

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

req.session.savedDoc = someObject; 
req.session.errors = ['someThing', 'anotherThing', 'thirdThing'];
req.session.message = 'someString'
Run Code Online (Sandbox Code Playgroud)

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

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

// Delete all session values
delete req.session.savedDoc;
delete req.session.errors;
delete req.session.message;
Run Code Online (Sandbox Code Playgroud)

Dav*_*ugg 118

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

for (var variableKey in vartoClear){
    if (vartoClear.hasOwnProperty(variableKey)){
        delete vartoClear[variableKey];
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么这个答案没有更多的upvotes ...这实际上清除了对象,而不是创建一个新对象(如果旧对象被某些东西引用,旧数据仍然存在). (24认同)
  • 是的!什么@ basic6说.今天我遇到了这个问题,创建一个新对象打破了我的另一个参考.这应该是正确的答案. (2认同)
  • 某些 JavaScript 实现会在枚举属性时对删除属性感到困惑吗?或者“in”枚举的定义是否准确指定了如果在枚举期间添加和删除属性会发生什么? (2认同)

Vis*_*ioN 49

只需指定一个空对象:

req.session = {};
Run Code Online (Sandbox Code Playgroud)

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


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

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

会话对象可能包含由不同变量链接的数据,并且设置新的空对象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}
Run Code Online (Sandbox Code Playgroud)

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

通过设置有方法的对象的深度清洁@戴夫经由或更短Object.keys(其忽略在原型侧链特性,并且不需要为任何垫片的node.js):

Object.keys(object).forEach(function(key) { delete object[key]; });
Run Code Online (Sandbox Code Playgroud)

...将显式删除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 );       // {}, {}
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 这是一个有用的答案,但我觉得它并不完整,因为它实际上并没有从对象中删除所有属性.如果有2个对同一对象的引用,则req.session1和req.session2并指定req.session1 = {}.然后req.session2仍然保持相同,所有它仍然定义的属性 (52认同)
  • 虽然结果是一个空对象,但该对象现在引用了内存中的一个新点 - 即新对象.这意味着如果对该对象有任何双重引用,它现在就消失了.底线 - 这不是清空对象,而是用新的替换它. (15认同)
  • 这不符合OP的问题. (5认同)
  • 他认为它应该打印一个空物体,因为这就是问题所在.从对象中删除所有属性后,您将拥有一个空对象. (2认同)

icl*_*126 13

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

for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];
Run Code Online (Sandbox Code Playgroud)

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

function deleteProperties(objectToClean) {
  for (var x in objectToClean) if (objectToClean.hasOwnProperty(x)) delete objectToClean[x];
}
Run Code Online (Sandbox Code Playgroud)

对于您的情况,用法将是:

deleteProperties(req.session);
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

使用清洁方法:

var x = {a: 5};
var y = x;
deleteProperties(x);  // x and y are both empty and x === y
Run Code Online (Sandbox Code Playgroud)


yen*_*ent 6

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

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


Gab*_*son 5

如果您像这样关心性能,则可以使用地图

const map = new Map()
map.set("first", 1)
map.set("second", 1)
map.clear()
Run Code Online (Sandbox Code Playgroud)

这是一个O(1)操作,因此即使您有一个巨大的对象,您也不需要迭代 x 次来删除条目。