【《你不知道的JS(中卷)》】四、混合对象“类”

四、混合对象“类”:

​ 在研究类的具体机制之前,首先介绍 面向类的设计模式:实例化(instantiation)、继承(inheritance)和(相对)多态(polymorphism)。

一)、类理论:

​ 面向对象编程强调的是数据和操作数据的行为本质上是互相关联的。

1、“类“设计模式:

​ 类是一种设计模式,有多种高级设计模式建立在面向对象类的基础上:迭代器模式、观察者模式、工厂模式、单例模式等等

2、JavaScript中的”类“:

​ 尽管ES6中加入了class关键字,但是JS中实际上并没有类。由于类是一种设计模式,因此可以用一些方法近似实现类的功能。

二)、类的机制:

​ 在面向类的语言中,必须将类实例化才可以对抽象化的类进行操作。

  • 类通过复制操作被实例化为对象形式;
  • 类实例是由一个特殊的类方法共造的,这个方法名通常和类名相同,被称为构造函数;

三)、类的继承:

​ 我们常说子类继承父类,但是用子类DNA是继承父类DNA会更好理解。类通过继承和方法重写实现多态。

  • 多态并不表示子类和父类有关联,子类得到的只是父类的一份副本。类的继承其实就是复制。

  • 在大多数面向类语言中,可以使用super来在子类中引用父类。

  • 有些语言允许多重继承,这样会导致”钻石继承“,但是JS本身并不提供多重继承。

四)、混入:

​ 在继承或者实例化时,JS的对象机制并不会自动执行复制行为。即JS中只有对象,并不存在可以被实例化的“类”。JS使用 混入来模拟类的复制行为。

1、显式混入:

function mixin(sourceObj, targetObj) {
  for (var key in sourceObj) {
    // 只会在不存在的情况下复制
    if (!(key in targetObj)) {
      targetObj[key] = sourceObj[key];
    }
  }
  return targetObj;
}

var Vehicle = {
  engines: 1,
  ignition: function () {
    console.log("...")
  },
  drive: function () {
    this.ignition();
  }
};

var Car = mixin(Vehicle, {
  wheels: 4,
  drive: function() {
    Vehicle.drive.call(this);
    console.log("...");
  }
})
  • 函数实际上没有被复制,复制的是函数引用。

  • Vehicle.drive.call(this);就是我们所说的显式多态,这里利用显式绑定调用Vechicle对象的drive方法,并把this绑定在Car对象上,确保drive()在Car对象的上下文中执行。

  • 使用显式伪多态会使代码更加复杂、难以阅读并且南移维护。

  • 此外还有 混合复制、寄生继承两种显式混入。

2、隐式混入:

​ 类似显式伪多态,具有一样的问题。

五)、小结:

​ 类意味着复制,传统的类被实例化时,它的行为会被复制到实例中。类被继承时,行为也会被复制到子类中。

​ 混入模式可以用来模拟类的复制行为,但是通常会产生丑陋并且脆弱的语法。此外,显式混入实际上无法完全模拟类的复制行为,因为对象只能复制引用,无法复制被引用的对象或者函数本身。

​ 总结,在JS中模拟类得不偿失。

猜你喜欢

转载自www.cnblogs.com/enmac/p/13174564.html