Wyliczalna właściwość to taka, która może być uwzględniona i odwiedzana podczas for..in
pętli (lub podobnej iteracji właściwości, jak np Object.keys()
.).
Jeśli właściwość nie zostanie zidentyfikowana jako wyliczalna, pętla zignoruje, że znajduje się w obiekcie.
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"
Właściwość jest identyfikowana jako wyliczalna lub nie na podstawie własnego [[Enumerable]]
atrybutu . Możesz to zobaczyć jako część deskryptora właściwości :
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 }
Następnie for..in
pętla wykonuje iterację po nazwach właściwości obiektu.
var foo = { bar: 1, baz: 2};
for (var prop in foo)
console.log(prop); // outputs 'bar' and 'baz'
Ale ocenia swoją instrukcję - console.log(prop);
w tym przypadku - tylko dla tych właściwości, których [[Enumerable]]
atrybutem jest true
.
Ten warunek istnieje, ponieważ obiekty mają o wiele więcej właściwości , zwłaszcza z dziedziczenia :
console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]
Każda z tych właściwości nadal istnieje na obiekcie :
console.log('constructor' in foo); // true
console.log('toString' in foo); // true
// etc.
Ale są pomijane przez for..in
pętlę, ponieważ nie są wyliczalne.
var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');
console.log(descriptor.enumerable); // false
for-in
robi?