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

JavaScript类的get访问器是否为每个实例单独分配内存?

结论

你观察到的堆快照结果是正确的:写在class类体内的get访问器只会分配一次,由所有实例共享,不会增加单个实例的内存占用。

原理说明

ES6 class的语法本质是原型继承的语法糖,你在类体中定义的所有普通方法、get/set访问器,最终都会被挂载到构造函数的prototype属性指向的原型对象上:

// 你写的class语法,等价于以下原型操作
function Test() {}
Object.defineProperties(Test.prototype, {
  a: { get() { return 1; } },
  b: { get() { return 2; } },
  // 其余访问器同理
})

所有通过new Test()创建的实例,自身只会存储自定义的实例属性,以及一个隐式的内部指针[[Prototype]](也就是常说的__proto__)指向Test.prototype,访问实例上的属性时如果实例本身没有,就会沿着原型链向上查找原型上的访问器,因此不需要每个实例都单独存储一份get访问器。

适用条件与例外场景

这个结论是ECMAScript规范明确定义的行为,所有主流浏览器引擎(Chrome的V8、Firefox的SpiderMonkey、Safari的JavaScriptCore)都严格遵循,不存在兼容性问题,你做浏览器游戏可以放心依赖。只有两种例外情况会导致访问器被重复分配:

  • 你在构造函数内部为单个实例单独定义访问器,例如:
    class Test {
      constructor() {
        // 错误写法:每个实例都会单独创建一份get a函数,占用额外内存
        Object.defineProperty(this, 'a', { get() { return 1; } })
      }
    }
    
  • 你使用了实例字段语法定义箭头函数形式的访问器(实际不是访问器,是实例属性存箭头函数),也会导致每个实例单独存储:
    class Test {
      // 错误写法:这是实例属性,不是原型上的get访问器,每个实例单独存
      getA = () => 1;
    }
    

开发建议

对于内存要求高的浏览器游戏,你完全可以把所有通用的访问器、方法都定义在class类体中,不管加多少个都不会增加实例的内存开销,原型上的属性只会初始化一次,对整体内存占用的影响可以忽略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:15:03