过滤对象成员的好习惯用法(javascript)

过滤对象成员的好习惯用法(javascript),javascript,node.js,Javascript,Node.js,我想删除某个对象的某些成员(为了便于讨论,这些成员的键以“\”开头)。这样做的优雅方式是什么?天真的方式是: for (var i in obj) if (i[0] === '_') delete obj[i]; 但这会在迭代过程中修改底层对象。至少我想我可以 Object.keys(obj).forEach(function (i) { if (i[0] === '_') delete obj[i]; }); 或者在每次删除某个内容时使用一个笨拙的嵌套循环重新启动迭代 有没

我想删除某个对象的某些成员(为了便于讨论,这些成员的键以“\”开头)。这样做的优雅方式是什么?天真的方式是:

for (var i in obj) 
  if (i[0] === '_') 
    delete obj[i];
但这会在迭代过程中修改底层对象。至少我想我可以

Object.keys(obj).forEach(function (i) { if (i[0] === '_') delete obj[i]; });
或者在每次删除某个内容时使用一个笨拙的嵌套循环重新启动迭代

有没有更好的解决办法


编辑:在刚才的测试中,至少在node.js中,这个天真的解决方案实际上似乎是可行的。当然,for…in(需要)安全实施是可能的。有人知道吗?

为什么不创建一个要删除的姓名列表

var l = [];
for (var i in obj) 
  if (i[0] === '_') 
    l.push(i);
l.forEach(function(v){ delete obj[v]; });
这将在循环过程中修改对象;p

如果您多次使用此选项,则通用选项为:

Object.keys(obj).filter(function (v) {
    //filter the object values/keys by some conditions
}).forEach( del.bind(obj) );

function del (v) {
    delete this[v];
}

另一种方法是创建一个返回过滤对象的函数。我更喜欢这种解决方案,以避免对代码的其他部分产生附带影响,这些部分包含对被修改对象的引用

function filterObject(obj) {
  var filtered = new Object();
  for (var i in obj)
    if (i[0] != '_')
      filtered[i] = obj[i];
    return filtered;
}

你不必为此担心。§12.6.4的摘录明确指出(我强调):

枚举属性的机制和顺序(中的步骤6.a) 未指定第一种算法(第二种算法中的步骤7.a)。 枚举过程中可能会删除正在枚举的对象的属性。如果在期间未访问过的财产 枚举已删除,则不会访问它。如果是新的 属性被添加到正在过程中枚举的对象 枚举时,新添加的属性不保证 在活动枚举中访问。不得访问属性名称 在任何枚举中不止一次


在<代码>期间是否对对象进行修改。。。在循环中导致问题?毕竟,我看不出它与在
forEach()
回调中修改对象有多大不同。我认为
object.keys
会对对象中的键进行快照。也许那不是真的……并且假设(…in…)的
没有拍摄对象的快照。啊,对不起;我现在明白你的意思了。我还是不确定是不是。。。在这种情况下,
将失败,但这是一个有趣的问题。您可以将JSON.parse&JSON.stringify与替换函数一起使用,例如
函数(键,值){return(键[0]=“”)?未定义:值;}
。这只适用于JSON可序列化的ElementsHanks。不知道
过滤器
-1-“如果在枚举过程中尚未访问属性”-我想这里不是这样。@thejh,那么前面的句子适用<根据标准,代码>for..in对于删除属性是完全安全的。
function filterObject(obj) {
  var filtered = new Object();
  for (var i in obj)
    if (i[0] != '_')
      filtered[i] = obj[i];
    return filtered;
}