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

将方法挂载到原型或构造函数:二者差异及优劣分析

为何要将方法挂载到原型而非构造函数?

嘿,这个问题问到点子上了!虽然你测试里两种写法调用起来效果完全一致,但它们在内存占用、继承特性、代码维护性上的差异可不小,咱们掰开揉碎了说:

1. 内存效率天差地别

当你把方法直接写在构造函数里时,每创建一个实例,都会生成一个全新的函数副本。比如你创建1000个Aircraft实例,就会有1000个一模一样的totalCost函数在内存里躺着,纯纯的资源浪费。

但把方法挂载到原型上时,这个方法是所有实例共享的——不管你创建多少个实例,内存里只有这一个totalCost函数,所有实例都会通过原型链找到它。这在实例数量多的时候,内存节省效果特别明显。

咱们用代码验证下:

// 构造函数挂载方法
function Aircraft1(a,b,c) {
  this.manufacturer = a;
  this.totalCost = function() { return b*c; };
}
const planeA = new Aircraft1("Boeing",2,500000);
const planeB = new Aircraft1("Airbus",4,600000);
console.log(planeA.totalCost === planeB.totalCost); // false,是两个不同的函数

// 原型挂载方法
function Aircraft2(a,b,c) {
  this.manufacturer = a;
  this.numberOfEngines = b;
  this.costPerEngine = c;
}
Aircraft2.prototype.totalCost = function() { return this.numberOfEngines * this.costPerEngine; };
const planeC = new Aircraft2("Boeing",2,500000);
const planeD = new Aircraft2("Airbus",4,600000);
console.log(planeC.totalCost === planeD.totalCost); // true,共享同一个函数

2. 继承和扩展更灵活

如果你后续要创建Aircraft的子类(比如FighterJet),原型挂载的方法可以直接被子类继承,不用重复定义。而且如果后续需要修改这个方法,只需要修改原型上的版本,所有实例(包括子类实例)都会自动用上新的方法。

但如果方法在构造函数里,子类要么得重新写一遍方法,要么得在子类构造函数里调用父类构造函数,不仅冗余,后续修改也得改多个地方,维护成本很高。

3. 代码结构更清晰

把方法集中放在原型上,能让构造函数只负责初始化实例属性,方法和属性分离,代码逻辑更清晰,别人读你的代码时一眼就能区分“哪些是实例独有的属性”,“哪些是所有实例共享的方法”。

那什么时候适合把方法写在构造函数里?

当然也有例外:如果你的方法需要访问构造函数内部的私有闭包变量(也就是构造函数里定义的、没挂载到this上的变量),那只能把方法写在构造函数里。比如:

function Aircraft(a,b,c) {
  const secretCode = "TOP_SECRET"; // 私有闭包变量
  this.manufacturer = a;
  // 这个方法需要访问secretCode,只能放在构造函数里
  this.getSecretInfo = function() {
    return `${this.manufacturer} - ${secretCode}`;
  };
}

这种情况下,原型方法拿不到secretCode,只能用构造函数内的方法来实现。

总结一下:绝大多数场景下,优先把方法挂载到原型上——省内存、好继承、易维护;只有当方法依赖构造函数的私有闭包变量时,才考虑放在构造函数里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:39:43