借用构造函数继承需在子构造函数中用call/apply调用父构造函数并传参,确保实例属性独立且参数动态传入;组合继承则结合此法与object.create设置原型,es6中super()为其语法糖。

在借用构造函数继承中传递参数,核心是用 call 或 apply 在子构造函数内部显式调用父构造函数,并把参数传进去。这能确保每个子实例拥有独立的、带正确值的属性,而不是共享或丢失参数。
为什么必须在子构造函数里调用父构造函数
原型链继承(比如 Child.prototype = new Parent())会在设置原型时就执行一次 Parent,但此时没有子实例,也拿不到 new Child('Alice', 30) 中的真实参数。结果要么初始化为空,要么只能写死默认值,完全失去灵活性。
而借用构造函数是在每次创建子实例时才执行父构造函数,this 指向当前新对象,参数也能按需传入。
怎么正确传参:用 call 或 apply 绑定 this 并透传参数
call 和 apply 都能改变函数执行时的 this,区别只在参数写法:
-
Parent.call(this, name, age)—— 参数逐个列出,适合已知数量和顺序 -
Parent.apply(this, arguments)—— 把所有入参当数组传,适合兼容任意参数个数 -
Parent.call(this, ...args)—— ES6 展开语法,更简洁清晰
例如:
this.name = name;
this.hobbies = Array.isArray(hobbies) ? hobbies : [hobbies];
}
function Child(name, age, hobbies) {
// 关键:在这里传参
Parent.call(this, name, hobbies);
this.age = age;
}
const c1 = new Child('Tom', 28, ['coding', 'hiking']);
console.log(c1.name); // 'Tom'
console.log(c1.hobbies); // ['coding', 'hiking']
组合继承中参数传递的完整写法
只靠借用构造函数能传参、避免引用共享,但无法复用父类原型上的方法。所以通常搭配原型链使用,即“组合继承”:
- 子构造函数第一行调用
Parent.call(this, ...args)初始化实例属性 - 用
Object.create(Parent.prototype)设置原型,不触发父构造函数 - 手动修复
Child.prototype.constructor = Child
这样既保证每个 Child 实例有自己的一份 name、hobbies,又能调用 Parent.prototype.sayHi() 这类共享方法。
ES6 class 中 super() 就是它的语法糖
写 class Child extends Parent 时,constructor 中首行必须写 super(name, age)。它本质就是 Parent.call(this, name, age),只是自动处理了 this 绑定、原型链和 constructor 修复。
不写 super 会报错;写晚了(比如在 this 赋值之后)也会报错——因为子类构造函数中,this 必须由 super 初始化。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











