You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何带get访问器的类属性无法被Object.keys等方法获取?

问题解答

核心原因:类的getter默认不可枚举

你定义的bar是类原型上的getter属性,而JavaScript类中所有定义在原型上的成员(包括方法、getter/setter),默认的**enumerable(可枚举性)**都是false。

Object.keys()、Object.entries()、Object.values()这类方法只会遍历对象自有且可枚举的属性;for...in循环则会遍历对象自身及原型链上可枚举的属性。因为bar的enumerable为false,所以自然不会被这些方法/循环捕获到。

你可以通过Object.getOwnPropertyDescriptor验证这一点:

console.log(Object.getOwnPropertyDescriptor(Foo.prototype, 'bar'));
// 输出:{ get: [Function: get bar], set: undefined, enumerable: false, configurable: true }

如何让getter可被遍历?

有两种常见方式可以让bar变成可枚举属性:

1. 将getter定义为实例的自有可枚举属性

在类的构造函数中,用Object.defineProperty把getter绑定到实例上,并设置enumerable: true:

class Foo {
    constructor() {
        Object.defineProperty(this, 'bar', {
            get: () => 'barval',
            enumerable: true,
            configurable: true
        });
    }
}

2. 修改原型上getter的可枚举性

直接修改类原型上bar属性的enumerable配置:

class Foo {
    get bar() {
        return 'barval';
    }
}

// 修改原型属性的可枚举性
Object.defineProperty(Foo.prototype, 'bar', {
    enumerable: true
});

或者用ES2022+的类静态块来完成配置,写法更优雅:

class Foo {
    static {
        Object.defineProperty(this.prototype, 'bar', {
            get: () => 'barval',
            enumerable: true
        });
    }
}

验证效果

修改后再运行测试代码,就能得到预期结果:

const foo = new Foo();
console.log(foo.bar,            // barval
    Object.keys(foo),           // ["bar"]
    Object.entries(foo),        // [["bar", "barval"]]
    Object.values(foo));        // ["barval"]
for (let key in foo)
    console.log(key, foo[key]); // 输出:bar barval

内容的提问来源于stack exchange,提问作者nicfv

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:10:19