借用构造函数实现属性继承,即在子类构造函数中用call/apply调用父类构造函数并绑定this,使每个子类实例拥有独立的属性副本,避免共享;但不继承原型方法,且可能造成内存浪费。

构造函数通过 借用构造函数(经典继承) 实现属性继承,核心是在子类构造函数内部用 call() 或 apply() 显式调用父类构造函数,并将 this 绑定到当前子类实例上。这样父类中定义在 this 上的属性(包括基本类型和引用类型)就会被“复制”到每个子类实例中,而非共享。
关键操作步骤
以下是最典型的实现方式:
- 定义父类构造函数,把需要继承的属性挂载在
this上(如this.name、this.colors) - 定义子类构造函数,在其内部第一行用
Parent.call(this, ...args)调用父类 - 确保传入的参数与父类期望一致,
this指向新创建的子类实例 - 后续可继续为子类实例添加专属属性(如
this.age)
为什么能避免属性共享?
因为每次创建子类实例时,父类构造函数都会被独立执行一次,每个实例都拥有自己的一份属性副本:
- 基本类型(如
name、age)天然独立 - 引用类型(如数组
colors)也会被重新初始化,各实例互不影响
一个简洁示例
注意:只继承属性,不继承原型方法
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue'];
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name); // ✅ 关键:借用父构造函数
this.age = age; // ✅ 子类自有属性
}
const c1 = new Child('Alice', 12);
c1.colors.push('green');
console.log(c1.colors); // ['red', 'blue', 'green']
const c2 = new Child('Bob', 13);
console.log(c2.colors); // ['red', 'blue'] —— 不受 c1 影响
console.log(c2.sayName); // undefined —— 原型方法未被继承
局限性要清楚
- 父类原型上的方法(如
sayName)不会被继承,子类实例无法访问 - 每次创建实例都重新创建父类中定义在
this上的方法(如果有的话),造成内存浪费 - 适合用于纯属性继承场景,通常需搭配其他方式(如原型链或
Object.create)补全方法继承











