关于 JavaScript 对象的方法不可枚举的困惑

Joj*_*oji 2 javascript ecmascript-6

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'
}

Run Code Online (Sandbox Code Playgroud)

我发现只有method1andmethod2是在循环中打印出来的for...in,这意味着它们是可枚举的。但是method2不会出现在循环中,这意味着它是不可枚举的。我想知道是什么造成了这里的差异?为什么method2在这种情况下它是不可枚举的?

另外,我发现如果我直接在对象文字中定义该方法,那么它又是可枚举的:

const object2 = {
  method2() {
    // Now this is enumerable
  }
}
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 5

类原型方法是不可枚举的 - 这就是语法的设计方式:

class X {
  method() {
  }
}

console.log(Object.getOwnPropertyDescriptor(X.prototype, 'method').enumerable);
Run Code Online (Sandbox Code Playgroud)

请参阅ClassDefinitionEvaluation中的CreateMethodProperty,它要求类方法是不可枚举的。

相反,类字段语法(即someProperty = someExpression 直接在类主体内部this.someProperty = someExpression)是在构造函数内部运行的语法糖。对对象上不存在的属性进行普通赋值却会导致该属性可枚举。

class RandomObject {
  method3 = function() {}
}
Run Code Online (Sandbox Code Playgroud)

相当于

class RandomObject {
  constructor() {
    this.method3 = function() {}
  }
}
Run Code Online (Sandbox Code Playgroud)

对于普通对象上的方法,请参阅PropertyDefinitionEvaluation,它描述了如何在对象文字中创建属性(包括方法)。它将执行

返回 ?MethodDefinition 使用参数对象和可枚举对 MethodDefinition 进行评估。

其中enumerable已设置trueObjectLiterals