跟着书本学JavaScript设计模式(原型模式)

162 阅读2分钟

原型模式

用原型实例指向创建对象的类,使用创建新的对象的类共享原型对象的属性以及方法。

    // 创建一个图片轮播类
    var LoopImages = function (imgArr, container) {
      this.imagesArray = imgArr; // 轮播图片数组
      this.container = this.container; // 轮播图片容器
      this.createImage = function () { }; // 创建轮播图图片
      this.changeImage = function () { }; // 切换下一张图片
    }
    // 新建子类
    // 上下滑动切换类
    var SliderLoopImg = function (imgArr, container) {
      // 构造函数继承图片轮播类
      LoopImages.call(this, imgArr, container);
      // 重写切换图片方法
      this.changeImage = function () {
        console.log('SlideLoopImg changeImage function');
      }
    }
    // 渐隐切换类
    var FadeLoopImg = function (imgArr, container, arrow) {
      LoopImages.call(this, imgArr, container);
      // 切换箭头私有变量
      this.arrow = arrow;
      // 重写切换图片方法
      this.changeImage = function () {
        console.log('FadeLoopImg changeImage function');
      }
    }

    // 测试代码
    // 实例化一个渐变图片类
    var fadeImg = new FadeLoopImg([
      '01.jpg',
      '02.jpg',
      '03.jpg',
      '04.jpg',
    ], 'slide', [
      'left.jpg',
      'right.jpg'
    ]);

    fadeImg.changeImage(); // FadeLoopImg changeImage function


最优解决方案

由于使用的是构造函数式继承,如果在基类中存在一些消耗资源比较大的方法也要一一复制,所以我们可以将这类方法通过原型的方式进行继承。

    var LoopImages = function (imgArr, container) {
      this.imageArray = imgArr;
      this.container = container;
    }
    LoopImages.prototype = {
      createImage: function () { },
      changeImage: function () { },
    };

    // 子类
    // 上下滑动切换类
    var SlideLoopImg = function (imgArr, container) {
      LoopImages.call(this, imgArr, container);
    }
    SlideLoopImg.prototype = new LoopImages();
    SlideLoopImg.prototype = {
      changeImage: function () {
        console.log('SlideLoopImg changeImage function');
      }
    }

    // 渐隐切换类
    var FadeLoopImg = function (imgArr, container, arrow) {
      LoopImages.call(this, imgArr, container);
      this.arrows = arrow;
    }
    FadeLoopImg.prototype = new LoopImages();
    FadeLoopImg.prototype.changeImage = function () {
      console.log('FadeLoopImg changeImage function');
    }

    // 测试用例
    var fadeImg = new FadeLoopImg([
      '01.jpg',
      '02.jpg',
      '03.jpg',
      '04.jpg',
    ], 'slide', [
      'left.jpg',
      'right.jpg'
    ]);
    console.log(fadeImg.container); // slide
    fadeImg.changeImage(); // FadeLoopImg changeImage function

原型拓展

原型对象是一个共享的对象,无论是父类的实例对象还是子类的继承,都是对他的一个指向引用,所以原型对象才会被共享。既然被共享,那么对原型对象的扩展,不论子类或者父类的实例对象都会继承下来。

    LoopImages.prototype.getImageLength = function () {
      return this.imageArray.length;
    }

    FadeLoopImg.prototype.getContainer = function () {
      return this.container;
    }
    console.log(fadeImg.getContainer());
    console.log(fadeImg.getImageLength())


原型继承

    function prototypeExtend() {
      var F = function () { };
      for (var i = 0; i < arguments.length; i++) {
        for (const j in arguments[i]) {
          F.prototype[j] = arguments[i][j];
        }
      }
      return new F();
    }


总结

原型模式可以让多个对象分享同一个原型对象的属性和方法,这也是一种继承方式,不过这种继承的实现是不需要创建的,而是将 原型对象分享给那些继承的对象。当然有时需要让每个继承对象独立拥有一份原型对象,此时我们需要对原型对象进行复制。