列挙可能なプロパティとは、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]]
属性によって列挙可能かどうかによって識別されます。これは、プロパティの記述子の一部として表示できます。
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
。
特に継承から、オブジェクトにはさらに多くのプロパティがあるため、この条件が整っています。
console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]
これらの各プロパティはまだオブジェクトに存在します:
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
for-in
いますか?