构造函数加原型模式是JavaScript最经典对象创建方式,构造函数初始化实例属性(含引用类型),原型挂载共享方法,兼顾独立性、共享性与类型识别。

构造函数加原型模式是 JavaScript 中最经典、最实用的对象创建方式,它兼顾了实例属性的独立性和方法的共享性,避免了内存浪费,也保留了类型识别能力。
构造函数负责实例属性
把每个对象独有的数据(比如 name、age、数组副本)放在构造函数里,用 this 赋值。这样每次 new 都生成一份独立副本,互不影响。
- 引用类型属性(如
this.colors = ['red', 'blue'])必须在构造函数中初始化,否则多个实例会共享同一份数组 - 不要在构造函数里定义方法,否则每个实例都新建一个函数对象,造成冗余
原型负责共享方法和属性
所有实例共用的行为(如 sayName、toString)统一挂到构造函数的 prototype 上。这样只创建一次,所有实例通过原型链访问。
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- 写法:
Person.prototype.sayName = function() { console.log(this.name); }; - 可批量添加:
Object.assign(Person.prototype, { sayName() {}, walk() {} }); - 避免直接赋值
Person.prototype = { ... },否则会丢失默认的constructor指向
组合写法示例(推荐结构)
以下是一个清晰、可维护的标准写法:
function Person(name, age) {
this.name = name;
this.age = age;
this.friends = ['Alice']; // 独立副本
}
Person.prototype.sayName = function() {
return this.name;
};
Person.prototype.haveBirthday = function() {
this.age++;
};
- new 出的每个
person1、person2都有自己name、age和friends - 但
sayName和haveBirthday是同一个函数,在内存中仅存在一份 -
person1 instanceof Person返回 true,类型识别正常
注意 constructor 的修复
如果用 Object.assign 或批量替换 prototype,记得手动恢复 constructor:
- 错误写法:
Person.prototype = { sayName() {} };→ 此时person.constructor === Object - 正确写法:
Person.prototype = { constructor: Person, sayName() {} }; - 或更稳妥:
Object.defineProperty(Person.prototype, 'constructor', { value: Person, writable: true, configurable: true });










