ES6 class中定义的普通方法默认是原型方法,所有实例共享同一函数引用;只有在constructor中用this显式赋值的方法才是每个实例独有的“实例方法”。

在 ES6 的 class 中,实例方法和原型方法本质上是同一回事——写在类体内的普通方法,默认就是定义在原型上的,也就是原型方法。所谓“实例方法”,只是指能被实例调用的方法,它并不意味着每个实例都拥有独立副本;真正造成“实例独有”的,是手动把方法赋给 this 的写法,但这属于非常规操作,且容易引发内存和性能问题。
Class 中定义的普通方法就是原型方法
只要你在 class 大括号内、constructor 外直接声明一个方法(不加 static),它就会被自动挂载到类的 prototype 上:
- 所有实例共享同一个函数引用,节省内存
- 方法中的
this指向调用它的实例 - 可通过
实例.__proto__.方法名或类名.prototype.方法名访问
例如:
class Person {constructor(name) { this.name = name; }
sayHi() { console.log(`Hi, I'm ${this.name}`); }
}
const p1 = new Person('Alice');
const p2 = new Person('Bob');
console.log(p1.sayHi === p2.sayHi); // true ← 同一个函数
真正的“实例方法”需显式绑定到 this
如果你在 constructor 中用 this.xxx = function() {...} 的方式定义方法,那它才是每个实例独有的“实例方法”:
立即学习“Java免费学习笔记(深入)”;
- 每次创建实例都会生成一份新函数,占用更多内存
- 无法通过原型链共享,也不能被子类继承(除非手动复制)
- 常见于需要闭包捕获构造时局部变量的场景,但应谨慎使用
例如:
class Counter {constructor(init) {
let count = init;
this.increment = () => count++; // 闭包捕获 count
}
}
const c1 = new Counter(0);
const c2 = new Counter(10);
console.log(c1.increment === c2.increment); // false ← 各自独立
如何验证方法在哪一层
你可以通过以下方式快速判断一个方法属于原型还是实例:
-
Object.getPrototypeOf(实例)查看原型对象上有哪些方法 -
实例.hasOwnProperty('方法名')返回false→ 说明不在实例自身,而在原型上 -
实例.方法名能调用 +实例.方法名 === 类名.prototype.方法名为true→ 典型原型方法
静态方法不是实例/原型方法
补充一点:用 static 声明的方法既不属于实例,也不属于原型,而是直接挂在类本身上,只能通过 类名.方法名 调用,不能被实例访问。


















