推荐答案
-- -------------------- ---- ------- -------- ------------ - --------- - ----- ----------- - ------- ------- --------- - ------------------------ - ---------- - ----------------------- -- -------- ----------- ---- - ----------------- ------ -- -------- -------- - ---- - --------------- - -------------------------------- -- ----- --------------------------- - ------ -- -------- ---------------------- - ---------- - --------------------- - ----- ------ - --- -------------- ---- ----- ------ - --- ------------ ---- ----------------------------- ------------------------- -- --- ----- ----------------- -- --- ----- --------------------------- -- --- ------- ------- -------- --------- ---------------- -- --- -- ------------------------- -- --- --- ----------------- -- --- --- --------------------------- -- --- ------- ------- -------- ---------------- ----- --
本题详细解读
原型链继承是 JavaScript 中实现继承的一种方式,它通过将子类型的原型设置为父类型的实例来实现继承。这样,子类型就可以访问父类型原型上的属性和方法。
核心思想:
让子类型的原型(Child.prototype
)指向父类型的实例(Parent.prototype
), 从而建立一条原型链,使得子类型实例能够访问父类型原型上的属性和方法。
实现步骤:
创建父类型构造函数: 定义一个父类型的构造函数
Parent
,并在其原型上添加需要被继承的属性或方法。创建子类型构造函数: 定义一个子类型的构造函数
Child
。借用构造函数继承属性: 在
Child
构造函数内部,使用Parent.call(this, ...)
来调用Parent
构造函数,这样就可以在Child
的实例中创建父类型的属性,确保父类型实例属性的隔离,避免共享。原型链继承方法: 使用
Child.prototype = Object.create(Parent.prototype);
将子类型的原型Child.prototype
设置为父类型原型Parent.prototype
的一个新对象,这里使用Object.create()
可以避免直接使用new Parent()
而可能导致的额外属性。修正构造函数指向: 将
Child.prototype.constructor
指向Child
构造函数本身, 否则原型链继承后,构造函数会指向Parent
。子类型添加特有方法: 可以在
Child.prototype
上添加子类型特有的方法。
优点:
- 实现简单:原型链继承是JavaScript中最基本的继承方式,实现起来比较简单。
- 父类型原型上的方法可以被子类型共享:子类型实例可以访问父类型原型上的方法。
缺点:
引用类型共享问题: 通过原型链继承,父类型实例属性的引用类型会被子类型实例共享。例如,如果
Parent
中有一个colors
数组,多个Child
实例会共享同一个colors
数组,修改一个实例的colors
会影响到其他实例。 这就是为什么在上述代码中,在Child构造函数内部使用了Parent.call(this, name);
来借用构造函数,使得父类的属性变成子类的实例属性。创建子类型实例时,不能向父类型的构造函数传递参数: 因为
Child.prototype
是被设置为Parent
的实例的,这意味着,在执行Child.prototype = new Parent()
时,Parent
的构造函数会被执行,而这个Parent
的执行没有办法接收任何参数。
改进方法:
通过 组合继承(借用构造函数+原型链继承),可以结合借用构造函数来实现父类型实例属性的隔离,并使用原型链继承父类原型上的方法,从而解决上述问题。上述推荐答案代码即展示了组合继承的实现方式。