封装的目的

  • 定义变量不会污染外部
  • 能够作为一个模块调用

好的封装

  • 变量外部不可见
  • 调用接口使用
  • 留出扩展接口

封装对象时的设计模式

创建一个对象的模式

  1. 工厂模式

    • 目的:方便大量创建类似对象
    • 应用场景:当某个对象需要经常创建的时候
    • 例:创建不同类型的弹窗

      /* 
      // 1.0 版本
      function infoPop() { }
      function confirmPop() { }
      function cancelPop() { }
      function pop(type, color, content) {
      switch (type) {
        case 'infoPop':
          return new infoPop(content, color);
        case 'confirmPop':
          return new confirmPop(content, color);
        case 'cancelPop':
          return new cancelPop(content, color);
      }
      } */
      // 2.0版本 
      // 方法挂载到pop函数原型上,需要新增弹窗只需要在在原型上新增方法即可
      (function () {
      function pop(type, color, content) {
        if (this instanceof pop) {
          // 兼容通过new操作符新建pop对象
          return new this[type](type, color, content)
        }
        return new pop(type, color, content)
      }
      pop.prototype.infoPop = function () { }
      pop.prototype.confirmPop = function () { }
      pop.prototype.cancelPop = function () { }
      window.pop = pop
      })()
      
      var data = [
      {
        type: 'infoPop',
        content: 'hello',
        color: 'red'
      },
      {
        type: 'confirmPop',
        content: 'good good study',
        color: 'yellow'
      },
      {
        type: 'confirmPop',
        content: 'good good study',
        color: 'green'
      },
      ];
      data.forEach((item) => {
      console.log(pop(item.type, item.content, item.color));
      })
      data.forEach((item) => {
      console.log(new pop(item.type, item.content, item.color));
      })
  2. 建造者模式

    • 目的:组合出一个全局对象
    • 应用场景:当要创建单个、庞大的组合对象时
    • 把一个复杂的类的各个部分,拆分成独立的类,再在最终类里组合。
    • 例1:编辑器插件,初始化时需要配置大量参数,内部功能很多,一般使用时只需要一个编辑器对象

      (function () {
      function Editor() {
        this.init = new initHTML()
        this.fontControl = new fontControl()
        this.stateControl = new stateControl()
      }
      function initHTML() { }
      initHTML.prototype.initState = function () { }
      function fontControl() { }
      fontControl.prototype.changeColor = function () { }
      function stateControl() {
        // 存储状态的数组
        this.state = []
        this.nowstate = 0
      }
      stateControl.prototype.saveState = function () { }
      stateControl.prototype.stateBack = function () {
        var state = this.state[this.nowstate - 1]
        // 状态回滚时,直接调用fontControl类的方法
        this.fontControl.changeColor(state.color)
        this.fontControl.changeFontSize(state.fontsize)
      }
      window.Editor = Editor
      })()
    • 例2:Vue的初始化

      function Vue(options) {
          // 必须使用new操作符
          if (!(this instanceof Vue)) {
              warn('Vue is a constructor and should be called with the `new` keyword');
          }
          this._init(options);
      }
      initMixin(Vue);
      stateMixin(Vue);
      eventsMixin(Vue);
      lifecycleMixin(Vue);
      renderMixin(Vue);
  3. 单例模式

    • 目的:确保全局只有一个对象
    • 应用场景:避免重复新建,避免多个对象相互干扰
    • 基本结构

      // 定义一个方法(getInstance),只允许通过此方法拿到类的同一实例化对象
      let Singleton = function (name) {
          this.name = name
      }
      Singleton.getInstance = function (name) {
          if (this.instance) {
              return this.instance
          }
          return this.instance = new Singleton(name)
      }
      let s = Singleton.getInstance('hello')
      console.log(s)
      console.log(s.name) // 'hello'
      let g = Singleton.getInstance('hi')
      console.log(g.name) // 'hello'
      console.log(g === s) // true
      • 例1:全局数据储存对象

        function store() {
          this.store = {}
          // 在每次通过store创建对象前判断store.install是否有值
          // 有则说明对象已经被创建过
          if (store.install) {
            return store.install;
          }
          // 在类store上挂载一个属性install,使其指向this
          // 当通过类创建对象时,store.install就等于创建出来的对象
          store.install = this;
        }
        store.install = null;
        var s1 = new store()
        var s2 = new store()
        console.log(s1 === s2)
      • 例2:vue-router全局必须只有一个

CSep27
37 声望1 粉丝

学习中...整理中...