for...in

for...in语句以任意顺序遍历一个对象的除Symbol以外的可枚举属性。

语法

for (variable in object)
  statement
variable
在每次迭代时,variable会被赋值为不同的属性名。
object
非Symbol类型的可枚举属性被迭代的对象。

数组迭代和 for...in

提示:for...in不应该用于迭代一个关注索引顺序的 Array

仅迭代自身的属性

如果你只要考虑对象本身的属性,而不是它的原型,那么使用 getOwnPropertyNames() 或执行 hasOwnProperty() 来确定某属性是否是对象本身的属性(也能使用propertyIsEnumerable)。或者,如果你知道不会有任何外部代码干扰,您可以使用检查方法扩展内置原型。

为什么用for ... in?

for ... in是为遍历对象属性而构建的,不建议与数组一起使用,数组可以用Array.prototype.forEach()for ... of,那么for ... in的到底有什么用呢?

它最常用的地方应该是用于调试,可以更方便的去检查对象属性(通过输出到控制台或其他方式)。尽管对于处理存储数据,数组更实用些,但是你在处理有key-value数据(比如属性用作“键”),需要检查其中的任何键是否为某值的情况时,还是推荐用for ... in

示例

下面的函数接受一个对象作为参数。被调用时迭代传入对象的所有可枚举属性然后返回一个所有属性名和其对应值的字符串。

var obj = {a:1, b:2, c:3};

for (var prop in obj) {
  console.log("obj." + prop + " = " + obj[prop]);
}

// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.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(`obj.${prop} = ${obj[prop]}`);
  }
}

// Output:
// "obj.color = red"

规范

Specification Status Comment
ECMAScript (ECMA-262)
for...in statement
Living Standard
ECMAScript 2015 (6th Edition, ECMA-262)
for...in statement
Standard
ECMAScript 5.1 (ECMA-262)
for...in statement
Standard
ECMAScript 3rd Edition (ECMA-262)
for...in statement
Standard
ECMAScript 1st Edition (ECMA-262)
for...in statement
Standard Initial definition.

浏览器兼容

BCD tables only load in the browser

兼容性:初始化函数表达式

在 SpiderMonkey 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37) 版本之前,可以在使用一个初始化表达式(i=0)在一个for...in循环中:

var obj = {a: 1, b: 2, c: 3};
for (var i = 0 in obj) {
  console.log(obj[i]);
}
// 1
// 2
// 3

这个非标准行为现在在版本40及更高版本中被忽略,并将在严格模式(bug 748550 和 bug 1164741中呈现SyntaxError("for-in loop head declarations may not have initializers")错误。

像其他引擎 V8(Chrome),Chakra (IE/Edge), JSC (WebKit/Safari) 正在研究去除这种不标准的行为。

相关链接