js是如何实现继承的用到了什么设计模式

135 阅读2分钟

JavaScript 中的继承机制与传统的面向对象编程语言(如 Java 或 C++)有所不同。在 JavaScript 中,并没有提供内置的关键字来直接支持类的概念,直到 ES6 引入了 class 关键字。但是,ES6 的 class 本质上也是基于函数的构造器加上原型链的语法糖。

原型链继承

在 ES6 之前的 JavaScript 版本中,最常用的继承方式是通过原型链来实现的。每个 JavaScript 对象都有一个内部属性 [[Prototype]],这个属性链接到另一个对象,称为原型对象。当我们访问一个对象的某个属性或方法时,如果该对象本身没有这样的属性或方法,那么 JavaScript 引擎会沿着原型链向上查找。

实现方式:

  1. 构造函数:创建一个函数,用来初始化对象的状态。
  2. 原型对象:构造函数的 prototype 属性指向一个对象,该对象中的属性和方法可以被构造函数创建的所有实例共享。

示例代码:

Javascript
深色版本
function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function() {
    return this.property;
};

function SubType() {
    SuperType.call(this); // 继承父类构造函数中的属性
}

// 继承父类的原型对象
SubType.prototype = new SuperType();

// 指定 constructor 属性
SubType.prototype.constructor = SubType;

SubType.prototype.getSubValue = function() {
    return this.property + " (subclass)";
};

借助 ES6 的 class 关键字

ES6 提供了一个更接近传统类定义的语法。然而,ES6 的 classsuper 关键字只是对原型链继承的一种抽象,并没有改变继承的本质。

示例代码:

Javascript
深色版本
class SuperType {
    constructor() {
        this.property = true;
    }

    getSuperValue() {
        return this.property;
    }
}

class SubType extends SuperType {
    constructor() {
        super(); // 调用父类构造函数
    }

    getSubValue() {
        return this.property + " (subclass)";
    }
}

设计模式

JavaScript 中实现继承的方式可以映射到不同的设计模式上,例如:

  • 组合模式:通过将对象组合在一起形成树形结构来表示“部分-整体”的层次结构。
  • 装饰模式:可以在不改变现有对象的情况下动态地增加功能。

然而,在 JavaScript 中实现继承并不直接对应于上述设计模式,而是更多地依赖于语言本身的特性,即原型链和构造函数。在某些情况下,为了实现特定的功能或者组织代码结构,可能会使用到这些设计模式。

总结

JavaScript 中的继承主要是通过原型链实现的,这使得继承机制非常灵活。ES6 的 classextends 关键字简化了这一过程,但它们仍然是基于原型的语言特性。在实际开发中,选择合适的继承方式以及是否使用设计模式,需要根据具体的应用场景来决定。