ECMAScript 2019:理解 JavaScript 中的原型链和继承机制

阅读时长 7 分钟读完

JavaScript 是一门面向对象的编程语言,其面向对象的特性主要体现在原型链和继承机制上。ECMAScript 2019 引入了一些新特性,其中包括原型链和继承机制的一些改进。本文将深入探讨 JavaScript 中的原型链和继承机制,为读者提供详细的学习和指导意义。

原型链

在 JavaScript 中,每个对象都有一个原型对象,它们形成了一个链式结构,这就是原型链。原型链上的每个对象都可以访问其原型对象的属性和方法。

创建原型对象

在 JavaScript 中,我们可以使用构造函数来创建对象。构造函数是一个普通的函数,但是它的返回值通常是一个新的对象。我们可以使用 new 关键字来创建一个对象,如下所示:

在上面的例子中,我们定义了一个 Person 构造函数,它有两个参数 nameage,并将它们分别赋值给了 this.namethis.age 属性。接着,我们使用 new 关键字来创建了一个 person 实例。

在 JavaScript 中,每个函数都有一个 prototype 属性,它是一个对象。我们可以通过给 prototype 添加属性和方法来为所有通过该构造函数创建的实例添加共享的属性和方法。例如:

在上面的例子中,我们在 Person 函数的原型对象上添加了一个 sayHello 方法,然后通过 person 实例调用了这个方法。

原型链的查找规则

当我们访问一个对象的属性或方法时,JavaScript 引擎会首先查找该对象本身是否存在该属性或方法,如果不存在,则会继续查找该对象的原型对象,直到找到该属性或方法或者到达原型链的末尾。

例如:

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

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

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

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

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

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

在上面的例子中,我们创建了一个 Animal 构造函数,并在其原型对象上添加了一个 sayHello 方法。接着,我们创建了一个 Dog 构造函数,并将其原型对象设置为一个 Animal 实例。最后,我们创建了一个 dog 实例,并调用了 sayHello 方法。由于 dog 实例本身没有 sayHello 方法,因此 JavaScript 引擎会查找它的原型对象,即 Dog.prototype,然后再查找 Animal.prototype,最终找到了 sayHello 方法。

使用 Object.create() 创建原型对象

除了使用构造函数和 prototype 来创建原型对象之外,还可以使用 Object.create() 方法来创建原型对象。Object.create() 方法接收一个原型对象作为参数,返回一个新的对象,该对象的原型对象就是传入的原型对象。

例如:

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

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

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

在上面的例子中,我们创建了一个 animal 对象,它有一个 sayHello 方法。接着,我们使用 Object.create() 方法创建了一个新的对象 dog,并将其原型对象设置为 animal。最后,我们调用了 dogsayHello 方法。

继承机制

在 JavaScript 中,继承是通过原型链实现的。我们可以通过让一个构造函数的原型对象指向另一个构造函数的实例来实现继承。

原型继承

原型继承是最常用的一种继承方式。我们可以通过让一个构造函数的原型对象指向另一个构造函数的实例来实现原型继承。

例如:

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

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

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

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

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

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

在上面的例子中,我们创建了一个 Animal 构造函数,并在其原型对象上添加了一个 sayHello 方法。接着,我们创建了一个 Dog 构造函数,并将其原型对象设置为一个 Animal 实例。最后,我们创建了一个 dog 实例,并调用了 sayHello 方法。由于 Dog.prototype 指向了一个 Animal 实例,因此 dog 实例就继承了 Animal 的属性和方法。

构造函数继承

构造函数继承是通过在子类构造函数内部调用父类构造函数来实现的。这种方式可以继承父类的属性,但是无法继承父类原型对象上的方法。

例如:

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

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

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

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

在上面的例子中,我们创建了一个 Animal 构造函数,并在其内部定义了一个 name 属性。接着,我们创建了一个 Dog 构造函数,并在其内部调用了 Animal 构造函数,从而继承了 Animalname 属性。最后,我们创建了一个 dog 实例,并输出了它的 nameage 属性。

组合继承

组合继承是将原型继承和构造函数继承结合起来的一种继承方式。它兼顾了原型继承和构造函数继承的优点,既可以继承父类的属性,又可以继承父类原型对象上的方法。

例如:

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

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

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

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

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

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

在上面的例子中,我们创建了一个 Animal 构造函数,并在其原型对象上添加了一个 sayHello 方法。接着,我们创建了一个 Dog 构造函数,并在其内部调用了 Animal 构造函数,从而继承了 Animalname 属性。然后,我们将 Dog.prototype 设置为一个 Animal 实例,从而继承了 Animal.prototype 上的方法。最后,我们创建了一个 dog 实例,并调用了 sayHello 方法,输出了它的 nameage 属性。

总结

JavaScript 中的原型链和继承机制是一种非常重要的面向对象特性,它们可以用来实现代码复用和继承。在本文中,我们深入探讨了 JavaScript 中的原型链和继承机制,并通过示例代码演示了它们的使用。希望本文能够为读者提供详细的学习和指导意义。

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

纠错
反馈