需用call是因为直接调用父类构造函数会使this指向错误,无法初始化子实例属性;必须用Parent.call(this, ...args)将父类逻辑绑定到子实例上,并手动设置原型链继承方法。

在 JavaScript 中,用 call 方法让子类构造函数调用父类构造函数,核心是把父类函数当作普通函数执行,并显式指定 this 指向子类新创建的实例。
为什么需要 call?
如果不调用父类构造函数,子类实例就无法继承父类在 this 上初始化的属性(比如 this.name = name)。直接写 Parent() 会让 this 指向全局对象(非严格模式)或 undefined(严格模式),完全起不到初始化子实例的作用。
基本写法:在子类构造函数中调用
在子类构造函数第一行,用 Parent.call(this, ...args) 把父类构造逻辑“借”过来运行:
// 父类
function Animal(name) {<br>
this.name = name;<br>
this.type = 'animal';<br>
}
// 子类
function Dog(name, breed) {<br>
// 关键:用 call 让 Animal 的 this 指向当前 Dog 实例<br>
Animal.call(this, name);<br>
this.breed = breed;<br>
}
注意原型链要另外设置
call 只解决构造函数内属性的继承,不处理方法继承。必须手动设置子类原型指向父类原型的副本(常用 Object.create):
立即学习“Java免费学习笔记(深入)”;
Dog.prototype = Object.create(Animal.prototype);- 补回构造器指向:
Dog.prototype.constructor = Dog; - 再添加子类独有方法:
Dog.prototype.bark = function() { ... };
ES6 class 中的对应写法(对比参考)
ES6 的 class 和 super() 底层正是基于类似 call 的机制实现的:
class Dog extends Animal {<br>
constructor(name, breed) {<br>
super(name); // 等价于 Animal.call(this, name)<br>
this.breed = breed;<br>
}<br>
}


















