JavaScript 内 new 绑定在实例化期间的内存分配

作者:袖梨 2026-07-04
JavaScript中new实例化分四步:先在堆中创建空对象,再将其__proto__指向构造函数原型,接着执行构造函数填充自有属性,最后返回堆中对象引用。

JavaScript 中 new 在实例化过程中,内存分配不是“一次性拍板”,而是分阶段、有策略地在堆内存中完成的。它不直接分配完整对象,而是先预留空间、再逐步填充,并通过原型链共享方法,避免重复开销。

堆内存中创建空对象

执行 new Person("Alice") 时,第一步是向堆内存申请一块新空间,生成一个**空对象**(如 {})。这个对象本身不含任何自有属性,但已具备基本对象结构,包括隐式原型 __proto__ —— 此刻它默认指向 Object.prototype,尚未与构造函数关联。

原型链接改写,不额外占内存

第二步将该空对象的 __proto__ 指针重定向到 Person.prototype。这一步只是修改引用地址,不分配新内存:
- __proto__ 是个指针,指向已存在的原型对象(通常在堆中早于实例就存在)
- 原型对象里的方法(如 Person.prototype.sayName)被所有实例共享,不随每个实例重复复制
- 实例自身只存储“独有数据”,比如 nameage 等自有属性

构造函数执行时填充实例数据

第三步调用 Person.call(新对象, "Alice"),此时 this 指向刚分配的堆内存地址,构造函数内部对 this.name = "Alice" 的赋值,就是往那块堆空间里写入字段:

  • 字符串 "Alice" 存在堆中(或字符串常量池),name 属性保存的是对该字符串的引用
  • 若构造函数内定义了函数(如 this.getName = function(){...}),该函数也会被创建在堆中,且每个实例都拥有一份 —— 这是常见内存浪费点
  • 推荐把方法挂到 prototype 上,让实例通过原型链访问,节省堆空间

返回对象始终指向堆中实体

第四步判断构造函数返回值:
- 若返回的是对象(含 null),则直接返回该对象(可能覆盖原实例)
- 否则,返回最初分配的那个堆内存对象
无论哪种情况,最终变量持有的都是一个**堆内存地址引用**,栈中只存这个地址,而非整个对象数据。

相关文章

精彩推荐