应将共享方法挂载到构造函数的 prototype 上,避免在构造函数中用 this 直接声明方法;ES6 class 方法默认挂原型,WeakMap 可配合原型模拟私有状态,箭头函数和 bind 仍产生独立副本。

构造函数中避免在 this 上直接声明方法,核心是把共享方法放到原型(prototype)上,让所有实例共用同一份函数,节省内存、提升性能。
把方法挂载到构造函数的 prototype 上
这是最经典、最直接的方式。每个实例不重复创建函数,而是通过原型链访问统一的方法:
- 定义构造函数时,不给
this赋值函数 - 改用
Constructor.prototype.methodName = function() { ... } - 实例调用时,自动沿原型链找到该方法
例如:
function Person(name) {
this.name = name; // 只放实例独有属性
}
Person.prototype.sayHello = function() {
console.log('Hello, I am ' + this.name);
};
const p1 = new Person('Alice');
const p2 = new Person('Bob');
console.log(p1.sayHello === p2.sayHello); // true —— 同一个函数引用
使用 ES6 class 语法(本质仍是原型机制)
class 是语法糖,内部方法默认定义在原型上,天然避免 this 绑定函数的问题:
- 类中的方法不会被复制到每个实例上
- 静态方法用
static关键字,挂载在构造函数本身 - 仍可通过
instance.__proto__或Object.getPrototypeOf(instance)查看原型方法
示例:
class Animal {
constructor(name) {
this.name = name;
}
speak() { // 自动挂到 Animal.prototype
console.log(this.name + ' makes a sound');
}
}
需要访问私有数据时:闭包 + 原型组合(谨慎使用)
如果方法需读写仅构造函数内可访问的变量(如真正的“私有字段”),不能直接放原型——因为原型方法无法访问闭包变量。此时可:
- 将私有数据存在实例属性(如
this._privateData),再在原型方法中使用 - 或用 WeakMap 模拟私有状态(ES6+),配合原型方法操作
- 避免在构造函数里用
this.method = function() {...}创建新函数
WeakMap 示例:
const privateData = new WeakMap();
function Counter(initial) {
privateData.set(this, { count: initial });
}
Counter.prototype.increment = function() {
const data = privateData.get(this);
data.count++;
};
Counter.prototype.getCount = function() {
return privateData.get(this).count;
};
箭头函数和 bind 不解决共享问题,慎用于构造函数内赋值
在构造函数中写 this.fn = () => {...} 或 this.fn = func.bind(this),依然会导致每个实例拥有独立函数副本:
- 箭头函数只是绑定
this,不是复用函数体 -
bind每次返回新函数,无法跨实例共享 - 这类写法适合需要绑定上下文的回调场景,但不是“共享方法”的解法
所以,若目标是共享,就不要在构造函数体内给 this 赋值函数。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











