我正在做这样的事情:
var myObj = {a:1, b:2, c:3, d:4};
for (var key in myObj){
if (someCondition){
delete(myObj[key]);
}
}
它在我尝试过的示例中工作得很好,但我不确定它在某些场景/浏览器中是否会出现意外行为。
修改被迭代的对象可以吗?
我正在做这样的事情:
var myObj = {a:1, b:2, c:3, d:4};
for (var key in myObj){
if (someCondition){
delete(myObj[key]);
}
}
它在我尝试过的示例中工作得很好,但我不确定它在某些场景/浏览器中是否会出现意外行为。
修改被迭代的对象可以吗?
第 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);
}
在这种情况下,您可能会迭代y
和删除x
,您仍然应该x
从原型中看到 ,但如果您x
首先迭代,那么y
您不应该看到第二个x
。
是的,它是安全的。
http://es5.github.com/#x12.6.4
12.6.4 for-in 语句
未指定枚举属性的机制和顺序(第一个算法中的步骤 6.a,第二个算法中的步骤 7.a)。被枚举对象的属性可能在枚举过程中被删除。如果在枚举期间还没有访问过的属性被删除,那么它就不会被访问。如果在枚举过程中向正在枚举的对象添加了新属性,则不能保证在活动枚举中访问新添加的属性。在任何枚举中不能多次访问属性名称。