翻译正在进行中。
概述
以任意序迭代一个对象的可枚举属性。每个不同的属性,语句都会被执行一次。
语法
for (variable in object) {
...
}
参数
variable- 每次迭代,一个不同的属性名将会赋予 variable
object- 可枚举属性被迭代的对象
描述
for...in 循环不遍历不可枚举属性。使用内建构造器例如 Array 和 Object 创建的对象拥有从 Object.prototype 和 String.prototype 继承的不可枚举属性,例如 String 的 indexOf 方法或者 Object 的 toString 方法。循环将迭代对象的所有可枚举属性,包括从它的构造函数的 prototype 继承而来的(包括被覆盖的内建属性)。
删除,添加或者修改属性
for...in 循环以任意序迭代一个对象的属性(浏览 delete operator 了解更多关于为什么开发者不能依赖于“看上去”的迭代顺序,至少是在跨浏览器情况下)。 如果一个属性在一次迭代中被修改,在稍后被访问,其在循环中的值是其在稍后时间的值。一个在被访问之前已经被删除的属性将不会在之后被访问。在迭代进行时被添加到对象的属性,可能在之后的迭代被访问,也可能被忽略。通常,在迭代过程中最好不要在对象上进行添加、修改或者删除属性的操作,除非是对当前正在被访问的属性。这里并不保证是否一个被添加的属性在迭代过程中会被访问到,不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问,不保证一个被删除的属性将会在它被删除之前被访问。
Array 迭代和 for...in
Note: for..in 不应该被用来迭代一个次序有重要作用的 Array .
数组索引仅是可枚举的整数名,其他方面和别的普通对象属性没有什么区别。for...in 并不能够保证返回的是按一定顺序的索引,但是它会返回所有可枚举属性,包括非整数名称的和继承的。
因为迭代的顺序是依赖于执行环境的,所以数组遍历不一定按次序访问元素。 因此当迭代那些访问次序重要的 arrays 时用整数索引去进行 for 循环 (或者使用 Array.prototype.forEach() 或 for...of 循环) 。
仅迭代自身的属性
If you only want to consider properties attached to the object itself, and not its prototypes, use getOwnPropertyNames() or perform a hasOwnProperty() check (propertyIsEnumerable can also be used). Alternatively, if you know there won't be any outside code interference, you can extend built-in prototypes with a check method.
例子
下面的函数接受一个对象作为参数。被调用时迭代传入对象的所有可枚举属性然后返回一个所有属性名和其对应值的字符串。
var o = {a:1, b:2, c:3};
function show_props(obj, objName) {
var result = "";
for (var prop in obj) {
result += objName + "." + prop + " = " + obj[prop];
}
return result;
}
alert(show_props(o, "o")); /* alerts: o.a = 1 o.b = 2 o.c = 3 */
下面的函数阐述了 hasOwnProperty() 的用法: 获得隐藏的继承属性.
var triangle = {a:1, b:2, c:3};
function ColoredTriangle() {
this.color = "red";
}
ColoredTriangle.prototype = triangle;
var obj = new ColoredTriangle();
for (var prop in obj) {
if( obj.hasOwnProperty( prop ) ) {
console.log("o." + prop + " = " + obj[prop]);
}
}
// Output:
// "o.color = red"
规范
| 规范 | 状态 | Comment |
|---|---|---|
| ECMAScript 1st Edition. | Standard | Initial definition. |
| ECMAScript 5.1 (ECMA-262) for...in statement |
Standard | |
| ECMAScript 2015 (6th Edition, ECMA-262) for...in statement |
Standard | |
浏览器兼容性
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |
| Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |
Firefox-specific notes
- Prior to SpiderMonkey 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37), it was possible to use an initializer expression (
i=0) in afor...inloop:var obj = {a:1, b:2, c:3}; for(var i=0 in obj) { console.log(obj[i]); } // 1 // 2 // 3这种非标准的方式已经在40的版本之后被移除了. 现在开始它会抛出一个错误SyntaxError("for-in loop head declarations may not have initializers") (bug 748550).
相关
for...of- 一个类似的迭代属性值的语句for each in- 一个类似的但是迭代的是对象的属性的值而不是其属性名字的语句 (过时的)for- Generator expressions (uses the
for...insyntax) - Enumerability and ownership of properties
Object.getOwnPropertyNames()Object.prototype.hasOwnProperty()Array.prototype.forEach()