关于 JavaScript 对象的方法不可枚举的混淆


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

我发现只有method1method2for...in循环中被打印出来,这意味着它们是可枚举的。然而,method2没有出现在循环中,这意味着它是不可枚举的。我想知道是什么导致了这里的差异?为什么在这种情况下只有method2是不可枚举的?

而且,我发现如果我直接在对象字面量中定义方法,那么它又是可枚举的:

const object2 = {
method2() {
// Now this is enumerable
}
}

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

class X {
method() {
}
}
console.log(Object.getOwnPropertyDescriptor(X.prototype, 'method').enumerable);

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

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

class RandomObject {
method3 = function() {}
}

等价于

class RandomObject {
constructor() {
this.method3 = function() {}
}
}

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

返回?methoddefinition带参数object和enumerable的MethodDefinition的求值。

使用ObjectLiterals设置enumerabletrue

最新更新