将方法挂到原型对象上可节省内存,构造函数负责实例属性,原型负责共享方法;避免在原型上放置可变引用类型;class 是语法糖,底层仍基于原型机制。

把方法挂到原型对象上,而不是在每个实例里重复定义,是优化 JS 内存占用最直接有效的方式。
构造函数只管实例属性,原型负责共享方法
构造函数中定义的属性(如 this.name)属于每个实例私有,必须保留;但方法(如 greet、toString)通常所有实例行为一致,没必要每创建一个对象就复制一份。
- ❌ 错误写法(浪费内存):
function Person(name) {
this.name = name;
this.greet = function() { console.log('Hello ' + this.name); }; // 每个实例都新建函数 - ✅ 正确写法(节省内存):
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() { console.log('Hello ' + this.name); }; // 所有实例共用一个函数
避免原型上放可变引用类型值
原型是共享的,如果在原型上直接定义数组、对象等引用类型属性,所有实例会共用同一份数据,导致意外修改和状态污染。
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
- ❌ 危险示例:
Person.prototype.hobbies = [];
const p1 = new Person('Alice');
p1.hobbies.push('reading');
const p2 = new Person('Bob');
console.log(p2.hobbies); // ['reading'] —— 被 p1 改动了! - ✅ 安全做法:
把引用类型初始化逻辑移到构造函数中,确保每个实例拥有独立副本;原型只放纯函数或不可变值(如字符串、数字、布尔值)。
组合使用:构造函数 + 原型 是主流实践
兼顾类型识别、内存效率与代码可维护性:
- 用构造函数初始化实例专属数据(this.xxx)
- 用 Constructor.prototype.xxx 添加所有实例共享的方法
- 必要时手动修复 constructor 指向(防止被覆盖后丢失类型信息):
Person.prototype.constructor = Person;
现代替代方案:class 语法更简洁,底层仍是原型机制
ES6 的 class 本质是构造函数 + 原型的语法糖,自动把方法挂到原型上,天然规避手写错误:
- class Person {
constructor(name) { this.name = name; }
greet() { console.log('Hello ' + this.name); } // 自动绑定到 Person.prototype
} - 它不会在每次 new 时重复创建 greet 函数,内存表现和手动操作 prototype 完全一致。










