封装的目的
- 定义变量不会污染外部
- 能够作为一个模块调用
好的封装
- 变量外部不可见
- 调用接口使用
- 留出扩展接口
封装对象时的设计模式
创建一个对象的模式
-
工厂模式
- 目的:方便大量创建类似对象
- 应用场景:当某个对象需要经常创建的时候
-
例:创建不同类型的弹窗
/* // 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)); })
-
建造者模式
- 目的:组合出一个全局对象
- 应用场景:当要创建单个、庞大的组合对象时
- 把一个复杂的类的各个部分,拆分成独立的类,再在最终类里组合。
-
例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);
-
单例模式
- 目的:确保全局只有一个对象
- 应用场景:避免重复新建,避免多个对象相互干扰
-
基本结构
// 定义一个方法(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全局必须只有一个
-
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。