我有以下for循环,当我使用splice()删除一个项目时,我得到'seconds'是未定义的。我可以检查它是否未定义,但我觉得可能有一种更优雅的方式来做到这一点。他们的愿望是简单地删除一个项目,然后继续前进。

for (i = 0, len = Auction.auctions.length; i < len; i++) {
    auction = Auction.auctions[i];
    Auction.auctions[i]['seconds'] --;
    if (auction.seconds < 0) { 
        Auction.auctions.splice(i, 1);
    }           
}

当前回答

这是一个很常见的问题。解决方案是反向循环:

for (var i = Auction.auctions.length - 1; i >= 0; i--) {
    Auction.auctions[i].seconds--;
    if (Auction.auctions[i].seconds < 0) { 
        Auction.auctions.splice(i, 1);
    }
}

如果你把它们从末端取出来也没关系因为下标会在逆向过程中保留下来。

其他回答

你可以浏览一下,然后使用shift()

删除参数

        oldJson=[{firstName:'s1',lastName:'v1'},
                 {firstName:'s2',lastName:'v2'},
                 {firstName:'s3',lastName:'v3'}]
        
        newJson = oldJson.map(({...ele}) => {
          delete ele.firstName;
          return ele;
          })

它删除和创建新的数组,因为我们在每个对象上使用展开运算符,所以原始数组对象也不会受到损害

Auction.auctions = Auction.auctions.filter(function(el) {
  return --el["seconds"] > 0;
});

当您执行.splice()时,数组正在重新索引,这意味着当一个索引被删除时,您将跳过一个索引,并且缓存的.length已过时。

要修复它,你要么需要在.splice()后面递减i,要么简单地反向迭代…

var i = Auction.auctions.length
while (i--) {
    ...
    if (...) { 
        Auction.auctions.splice(i, 1);
    } 
}

这样,重新索引就不会影响迭代中的下一项,因为索引只影响从当前点到数组末尾的项,并且迭代中的下一项低于当前点。

如果你正在使用ES6+ -为什么不直接使用数组。过滤方法?

Auction.auctions = Auction.auctions.filter((auction) => {
  auction['seconds'] --;
  return (auction.seconds > 0)
})  

注意,在过滤器迭代过程中修改数组元素只对对象有效,而对基元值数组无效。