关于JavaScript对象方法枚举性差异的疑问:类中不同方式定义的方法为何枚举性不同?
method1 and method3 enumerable but method2 isn't in this JavaScript class? Let’s break down exactly why each method has different enumerability behavior—this all comes down to how JavaScript handles different method definition patterns in classes versus object literals.
1. method1 (assigned in the constructor)
When you write this.method1 = function() {} inside the class constructor, you’re directly adding a property to the instance object (object) when it’s created. Any property assigned directly to an instance like this has its enumerable flag set to true by default. That’s why it shows up in your for...in loop.
2. method2 (class prototype method)
The syntax method2() {} inside a class is shorthand for defining a method on the class’s prototype (i.e., RandomObject.prototype.method2). The ES6 class specification deliberately sets the enumerable flag to false for these prototype methods. This design choice helps distinguish "own" instance properties from inherited prototype methods, and since for...in only iterates over enumerable properties (own or inherited), this method doesn’t appear in the loop results.
3. method3 (class field syntax)
The method3 = function() {} syntax is standard class field syntax, which acts as syntactic sugar for moving the assignment into the constructor. In practice, this is identical to how method1 is defined: when an instance is created, this.method3 is assigned directly to the instance, making it an own enumerable property. That’s why it shows up alongside method1 in the loop.
Why object literal method2() is enumerable?
When you define method2() {} in an object literal, this is shorthand for method2: function() {}. Properties defined this way on an object literal have their enumerable flag set to true by default. This is a key distinction from class prototype methods: object literal methods are own enumerable properties of the object itself, while class prototype methods are non-enumerable properties on the prototype chain.
You can confirm these behaviors yourself by checking property descriptors with Object.getOwnPropertyDescriptor:
// Check class instance properties console.log(Object.getOwnPropertyDescriptor(object, 'method1')); // { enumerable: true, ... } console.log(Object.getOwnPropertyDescriptor(RandomObject.prototype, 'method2')); // { enumerable: false, ... } console.log(Object.getOwnPropertyDescriptor(object, 'method3')); // { enumerable: true, ... } // Check object literal property console.log(Object.getOwnPropertyDescriptor(object2, 'method2')); // { enumerable: true, ... }
内容的提问来源于stack exchange,提问作者Joji

