ECMAScript 2019:JavaScript 中的继承方式总结,理解其原理

阅读时长 6 分钟读完

JavaScript 是一种类型松散的语言,它支持多路触发,异步事件驱动等,并最好用于前端开发。为了使 JavaScript 拥有更加完整、更加完备的语言功能,ECMAScript 规范里面不断地增加新特性。其中,继承方式也是为数不多的,但它却是非常重要的,本文将来介绍 ES6 和 ES7 中支持的 JavaScript 继承方式并剖析其原理。

继承方式

1. 原型链继承

原型式继承相对来说比较简单,就是让一个对象继承另外一个对象的属性和方法,从而使它们成为一类。我们使用新的方式建立一个对象。

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

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

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

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

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

Child 的实例 new 子类的时候,就可以通过__proto__将 Child 的属性和方法链接到其原型对象上,也就实现了对 Parent 的属性和方法继承。

但缺点也很明显,就是共享父类属性,在许多实例需要改变父类的属性,我们就需要单独设置,而且当创建子类实例的时候不能直接往父类构造函数传递参数。

2. 借助构造函数继承

使用 call 或 apply 的方式,把父类的对象数据复制给子类对象。这样就设计到一个问题,就是无法继承父类的方法,子类只能继承这些方法的拷贝。

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

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

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

知道原理就不难发现这种方式有巨大的局限性,当然也可以通过 Child.prototype = new Parent() 的方式来解决继承问题,不过这样也会带来同样的问题:子类实例将会共享 Parent 的属性和方法。

3. 组合继承(伪经典继承)

原型链方法继承父类的属性和方法(并解决了共有属性和方法的问题),借用构造函数来实现继承父类对象的属性。

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

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

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

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

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

4. 原型式继承

原型式继承的方式其实是创建一个新的对象,然后利用 Object.create 创建一个原型,然后再通过 Object.create 方法进行增强、拷贝、继承一个新对象等操作。

虽然这个方式听上去也比较特别,但它的实质就是简化版的原型链继承,而且复制的属性、方法借助了 ES5 提供的 Object.create()

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

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

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

5. ES6 类式继承

ES6 中的类式继承对 JavaScript 继承的原生语法进行了封装和简化,让继承更加接近传统面向对象中的语言。

可以使用 extends 关键字来实现继承,子类的构造函数中通过关键字 super 则可以调用父类的构造函数。

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

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

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

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

6. ES7 中的 Object.setPrototypeOf 和 Object.assign 继承

ES7 引入的 Object.setPrototypeOf 方法和 Object.assign 方法来替换掉了原有的 Object.create 等等伪继承方法。

Object.setPrototypeOf 方法将一个指定的对象的原型设置成另一个对象或者是 null。并且,我们还需要在开头提示使用 ES2015+ 的语法。

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

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

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

Object.assign 方法虽然是比较常见的原型继承方式,但实际上它的本质并不是继承,它只能复制一个或多个源对象的自有属性到目标对象中。

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

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

总结

继承是一种极为重要的语言特性,在 JS 基础上高效使用 OOP 的思想是值得学习的,掌握继承方式有助于你更好地使用 JavaScript 语言,提高自己的编程能力。在实际应用中,请酌情选择不同继承方式,每种方式各有利弊,看具体情况而定。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6520b64195b1f8cacd825862

纠错
反馈