实现 JavaScript 继承的三种模式设计

JavaScript 是一门基于对象面向原型编程(prototype-based)的语言,而继承(inheritance)是面向对象编程中一个重要的概念。在 JavaScript 中,我们可以使用原型链(prototype chain)来实现对象之间的继承关系。本文将介绍三种常见的 JavaScript 继承模式,并提供详细的代码示例。

1. 原型链继承

原型链继承是 JavaScript 中最基本的继承方式。其思想是通过让子类的原型对象指向父类的实例对象,从而实现继承。具体实现如下:

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

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

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

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

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

这里我们定义了 ParentChild 两个构造函数,Parent 构造函数有一个 name 属性和一个 getName 方法,Child 构造函数为空。我们将 Child 的原型对象设置为一个 Parent 的实例对象,这样 Child 就继承了 Parent 的所有属性和方法。通过调用 child.getName(),我们可以看到 Child 实例成功地继承了 Parent 中的 getName 方法。

原型链继承的缺点是会产生多个实例共享同一个父类实例的问题。这是因为子类原型对象指向了同一个父类实例对象,而所有子类实例都会继承该原型对象。如果在某个子类实例中修改了父类实例的属性值,那么所有其他子类实例的该属性值也会被修改。这种情况通常不是我们所期望的。

2. 构造函数继承

为了解决原型链继承中存在的问题,我们可以考虑使用构造函数继承。其思想是在子类构造函数内部调用父类构造函数,并使用 callapply 方法将父类构造函数的作用域(this)绑定到子类实例上。具体实现如下:

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

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

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

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

这里我们定义了 ParentChild 两个构造函数,Parent 构造函数有一个 names 属性,Child 构造函数为空。在 Child 构造函数内部,我们调用了 Parent.call(this) 来执行 Parent 构造函数,并将其作用域绑定到 Child 实例上。这样一来,Child 就拥有了自己的 names 属性,而不是共享父类实例的那个属性。通过在两个不同的子类实例中添加元素,我们可以看到它们互不影响。

构造函数继承的缺点是无法继承父类原型对象上的方法和属性。因此,如果子类需要使用父类原型对象上的方法或属性,还需要通过将子类原型对象指向父类原型对象的方式进行扩展。

3. 组合继承

组合继承是原型链继承和构造函数继承的结合。其思想是使用原型链继承继承父类的方法和属性,使用构造函数继承继承父类的实例属性

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/32393