返回

带你读懂js原型,原型链,new与6种继承方式

前端

原型继承:JavaScript 继承机制的奥秘

在 JavaScript 的世界中,继承是一个至关重要的概念,它允许我们创建新的对象,这些对象从现有对象中继承属性和方法。而 原型继承 便是 JavaScript 实现继承的最为核心的机制之一,是深入理解 JavaScript 继承的关键所在。

原型:继承的基石

原型是 JavaScript 中实现继承的核心概念。原型 是一个内部属性,每个函数都会拥有它,它指向创建该函数时的父函数。原型扮演着 基类 的角色,它定义了该函数所创建的对象所共有的属性和方法。

JavaScript 采用了一种名为 原型链 的方式将对象连接在一起。每个对象都有一个内部属性 __proto__,指向它的原型。而原型的 __proto__ 属性又指向它的原型,以此类推。这种链状结构将对象与它们的基类联系起来,形成了一个继承的体系。

构造函数与原型的关系

构造函数 是用于创建对象的函数。它负责实例化对象,即为对象分配内存空间并初始化其属性。原型是构造函数的内部属性,指向创建该函数时的父函数的原型。

换句话说,当我们调用一个构造函数时,它会创建一个新对象,并将该对象的 __proto__ 属性指向构造函数的 prototype 属性。这样,新创建的对象便继承了父类原型的属性和方法。

6 种 JavaScript 继承方式

JavaScript 中常用的继承方式共有 6 种:

  • 原型链继承(最常见): 通过原型链实现继承,这是 JavaScript 中最基本最常见的继承方式。
  • 构造函数继承: 通过在子类构造函数中调用父类构造函数实现继承,这种方式不推荐使用,因为它会带来一些问题。
  • 组合继承(原型链继承 + 构造函数继承): 结合原型链继承和构造函数继承的优点,是一种较为完善的继承方式。
  • 原型式继承: 使用 Object.create() 方法创建新对象,该对象的原型对象为指定的对象。
  • 寄生式继承: 通过创建一个新对象,并将其附加到父类对象实现继承。
  • 寄生组合式继承(寄生式继承 + 组合继承): 结合寄生式继承和组合继承的优点。

new 的原理

new 关键字是 JavaScript 中用于创建新对象的语法糖。它的本质是:

  1. 创建一个空对象。
  2. 将该对象的 __proto__ 属性指向构造函数的 prototype 属性。
  3. 执行构造函数,并将该对象作为 this 的上下文。
  4. 返回该对象。

手写 new

我们也可以自己实现 new 操作符。手写 new 需要以下步骤:

  1. 创建一个空对象。
  2. 将该对象的 __proto__ 属性指向构造函数的 prototype 属性。
  3. 执行构造函数,并将该对象作为 this 的上下文。

Object.create() 方法

Object.create() 方法可以创建一个新对象,该对象的原型对象是指定的对象。这是一种实现原型继承的便捷方式,而且比使用 new 关键字更灵活。

总结

原型继承是 JavaScript 中实现继承的基石,它通过原型链将对象与它们的基类联系起来。理解原型继承对于深入理解 JavaScript 继承至关重要。JavaScript 中提供了多种继承方式,每种方式都有其优缺点。 new 关键字和 Object.create() 方法是 JavaScript 中创建新对象和实现原型继承的两种重要手段。

常见问题解答

  1. 原型和原型链有什么区别?
    原型是一个函数的内部属性,指向创建该函数时的父函数。而原型链是一系列对象之间的连接,它将对象与它们的基类联系起来。

  2. 如何判断一个对象是否继承自另一个对象?
    可以使用 Object.getPrototypeOf() 方法获取对象的原型。如果一个对象的原型的 __proto__ 属性指向另一个对象的原型,则这两个对象具有继承关系。

  3. 为什么不推荐使用构造函数继承?
    构造函数继承会带来一些问题,例如无法访问父类原型上的属性和方法。

  4. 哪种继承方式最常用?
    原型链继承是最常用也是最推荐的继承方式。

  5. 如何实现寄生式继承?
    寄生式继承可以通过创建一个新对象,并将其附加到父类对象实现。