Reputation: 5646
class RandomObject {
constructor() {
this.method1 = function() {}
}
method2() {
// only this is non enumerable
}
method3 = function() {}
}
const object = new RandomObject()
for (const prop in object) {
console.log(prop) // 'method1', 'method2'
}
I found that only method1
and method2
are printed out in the for...in
loop, meaning they are enumerable. However method2
doesn't show up in the loop, meaning it is non-enumerable. I wonder what caused the differences here? Why is that only method2
is non-enumerable in this case?
Also, I found that if I define the method directly in the object literal, then it is enumerable again:
const object2 = {
method2() {
// Now this is enumerable
}
}
Upvotes: 2
Views: 277
Reputation: 371098
Class prototype methods are non-enumerable - that's just the way the syntax was designed:
class X {
method() {
}
}
console.log(Object.getOwnPropertyDescriptor(X.prototype, 'method').enumerable);
See CreateMethodProperty in ClassDefinitionEvaluation, which requires that class methods be non-enumerable.
In contrast, class field syntax - that is, someProperty = someExpression
directly inside the class body - is syntax sugar for running this.someProperty = someExpression
inside the constructor. Ordinary assignment to a property that doesn't exist on the object yet results in the property being enumerable.
class RandomObject {
method3 = function() {}
}
is equivalent to
class RandomObject {
constructor() {
this.method3 = function() {}
}
}
With methods on ordinary objects, see PropertyDefinitionEvaluation, which describes how properties (including methods) get created in object literals. It'll carry out
Return ? MethodDefinitionEvaluation of MethodDefinition with arguments object and enumerable.
where enumerable
has been set to true
with ObjectLiterals.
Upvotes: 5