如何实现原型继承?请写出一个原型链继承的例子。

推荐答案

-- -------------------- ---- -------
-------- ------------ -
  --------- - -----
  ----------- - ------- ------- ---------
-

------------------------ - ---------- -
  -----------------------
--


-------- ----------- ---- -
  ----------------- ------ -- --------
  -------- - ----
-

--------------- - -------------------------------- -- -----
--------------------------- - ------  -- --------

---------------------- - ---------- -
    ---------------------
-


----- ------ - --- -------------- ----
----- ------ - --- ------------ ----

-----------------------------

-------------------------  -- --- -----
-----------------       -- --- -----
--------------------------- -- --- ------- ------- -------- ---------
----------------   -- --- --

-------------------------  -- --- ---
-----------------      -- --- ---
--------------------------- -- --- ------- ------- --------
---------------- ----- --

本题详细解读

原型链继承是 JavaScript 中实现继承的一种方式,它通过将子类型的原型设置为父类型的实例来实现继承。这样,子类型就可以访问父类型原型上的属性和方法。

核心思想:

让子类型的原型(Child.prototype)指向父类型的实例(Parent.prototype), 从而建立一条原型链,使得子类型实例能够访问父类型原型上的属性和方法。

实现步骤:

  1. 创建父类型构造函数: 定义一个父类型的构造函数 Parent,并在其原型上添加需要被继承的属性或方法。

  2. 创建子类型构造函数: 定义一个子类型的构造函数 Child

  3. 借用构造函数继承属性:Child 构造函数内部,使用 Parent.call(this, ...) 来调用 Parent 构造函数,这样就可以在 Child 的实例中创建父类型的属性,确保父类型实例属性的隔离,避免共享。

  4. 原型链继承方法: 使用 Child.prototype = Object.create(Parent.prototype); 将子类型的原型 Child.prototype 设置为父类型原型 Parent.prototype 的一个新对象,这里使用 Object.create() 可以避免直接使用 new Parent() 而可能导致的额外属性。

  5. 修正构造函数指向:Child.prototype.constructor 指向 Child 构造函数本身, 否则原型链继承后,构造函数会指向 Parent

  6. 子类型添加特有方法: 可以在 Child.prototype 上添加子类型特有的方法。

优点:

  • 实现简单:原型链继承是JavaScript中最基本的继承方式,实现起来比较简单。
  • 父类型原型上的方法可以被子类型共享:子类型实例可以访问父类型原型上的方法。

缺点:

  • 引用类型共享问题: 通过原型链继承,父类型实例属性的引用类型会被子类型实例共享。例如,如果 Parent 中有一个 colors 数组,多个 Child 实例会共享同一个 colors 数组,修改一个实例的 colors 会影响到其他实例。 这就是为什么在上述代码中,在Child构造函数内部使用了Parent.call(this, name); 来借用构造函数,使得父类的属性变成子类的实例属性。

  • 创建子类型实例时,不能向父类型的构造函数传递参数: 因为 Child.prototype 是被设置为 Parent 的实例的,这意味着,在执行 Child.prototype = new Parent() 时,Parent 的构造函数会被执行,而这个 Parent 的执行没有办法接收任何参数。

改进方法:

通过 组合继承(借用构造函数+原型链继承),可以结合借用构造函数来实现父类型实例属性的隔离,并使用原型链继承父类原型上的方法,从而解决上述问题。上述推荐答案代码即展示了组合继承的实现方式。

纠错
反馈