可枚举属性是可以在for..in 循环(或类似的属性迭代,如Object.keys())中包含和访问的属性。
如果一个属性未被识别为可枚举,循环将忽略它在对象内。
var obj = { key: 'val' };
console.log('toString' in obj); // true
console.log(typeof obj.toString); // "function"
for (var key in obj)
console.log(key); // "key"
属性由它自己的[[Enumerable]] attribute 标识为可枚举或不可枚举。您可以将其视为property's descriptor 的一部分:
var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar');
console.log(descriptor.enumerable); // true
console.log(descriptor.value); // 1
console.log(descriptor);
// { value: 1, writable: true, enumerable: true, configurable: true }
for..in 循环然后遍历对象的属性名称。
var foo = { bar: 1, baz: 2};
for (var prop in foo)
console.log(prop); // outputs 'bar' and 'baz'
但是,只评估它的声明——在这种情况下是console.log(prop);——对于那些[[Enumerable]]属性为true的属性。
这个条件成立是因为对象have many more properties,尤其是from inheritance:
console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]
这些属性中的每一个仍然是exists on the object:
console.log('constructor' in foo); // true
console.log('toString' in foo); // true
// etc.
但是,for..in 循环跳过了它们,因为它们不可枚举。
var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');
console.log(descriptor.enumerable); // false