Javascript:使用'for'删除正在迭代的对象的属性是否安全

wil*_*lvv 6 javascript

我正在做这样的事情:

var myObj = {a:1, b:2, c:3, d:4};

for (var key in myObj){
  if (someCondition){
    delete(myObj[key]);
  }
}
Run Code Online (Sandbox Code Playgroud)

它在我尝试过的示例中运行得很好,但我不确定它在某些场景/浏览器中是否会出现意外行为.

修改正在迭代的对象是否可以?

Mik*_*uel 8

第12.6.4节解释for..in了根据"下一个财产"的定义:

令P为obj的下一个属性的名称,其[[Enumerable]]属性为true.如果没有这样的属性,则返回(正常,V,空).

由于概念"下一个属性"即使在存在突变的情况下也很好地定义(尽管迭代顺序不是),因此delete在迭代期间不会引入未定义的行为.

有一个角落案例,delete取消掩盖原型属性

var obj = Object.create({ x: 1 });
obj.y = 2;
obj.x = 3;
for (var k in obj) {
  if (k == 'y') { delete obj.x; }
  alert(k);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你可以迭代y和删除x,你仍然应该看到x原型,但如果你x先迭代,那么y你不应该看到第二个x.


小智 6

是的,这是安全的.

http://es5.github.com/#x12.6.4

12.6.4 for-in语句

枚举属性的机制和顺序(第一个算法中的步骤6.a,第二个算法中的步骤7.a)未指定.枚举期间可以删除要枚举的对象的属性.如果删除枚举期间尚未访问的属性,则不会访问该属性.如果在枚举期间将新属性添加到要枚举的对象,则无法保证在活动枚举中访问新添加的属性.在任何枚举中不得多次访问属性名称.