前言
什么是设计模式?(Design pattern)
代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。————《菜鸟教程》总而言之,设计模式就是为了解决软件开发中一些遇到问题的目前解决最佳方案,是由软件工程师们一步一步摸索出来的,使来这些问题轻松化,简单化。本文主要讲解js设计模式中的单例模式以及装饰器模式
单例模式
核心:保证一个类,只有一个实例,并提供一个访问它的全局访问点### 实现一个简单的单例模式
下面我们来看一个简单的单例模式
function Person(name, age) {this.name = name;this.age = age
}
let jitao = new Person('计涛', 20)
let yc = new Person('严辰', 21)
console.log(jitao);
console.log(yc);
let Person = (function () {let instance = nullreturn function (name, age) {this.name = namethis.age = ageif(instance){return instance}return instance = this}
})()
// function Person(name, age) {
// this.name = name;
// this.age = age
// }
let jitao = new Person('计涛', 20)
let yc = new Person('严辰', 21)
console.log(jitao);
console.log(yc);
console.log(jitao===yc);
- 以上代码通过自执行函数和闭包将
instance
封装起来。并且返回了真正的单例构造方法。但如果哪天,我们需要在其中添加更多的元素,但又不想改写Person,我们该怎么办呢?我们可以通过代理来解决
通过代理实现单例模式
function Person(name, age) {this.name = name;this.age = age
}
Person.prototype.sayHello = function () {console.log(this.name)
}
let jitao = new Person('计涛', 20)
let yc = new Person('严辰', 21)
console.log(jitao)
console.log(yc)
console.log(jitao === yc)
我们先定义一个Person类,然后在它的原型上定义一个sayHello的方法,那么我们知道,这里不是单例模式,那如何在不改变上面代码的情况下建立一个单例模式呢?这里我们就可以建立一个代理类,来实现单例模式。
function Person(name, age) {this.name = name;this.age = age
}
Person.prototype.sayHello = function () {console.log(this.name)
}
let personProxy = (function () {let instance = nullreturn function (name,age) {if (instance) {return instance}return instance = new Person(name, age)}
})()
let jitao = new personProxy('计涛', 20)
let yc = new personProxy('严辰', 21)
console.log(jitao)
console.log(yc)
console.log(jitao === yc)
jitao.sayHello();
yc.sayHello();
装饰器模式
装饰器模式(Decorator)也可称之为装饰者模式,在不改变原有对象的基础上,对其进行包装,拓展,使原有对象可以满足更加复杂的需求。### 增强对象
举个简单的例子,我们定义一个学生类,要求学生需要会HTML、CSS、JS,
function Student(){}
Student.prototype.study = function(){console.log('html');console.log('css');console.log('js');
}
var jitao = new Student();
但为了找到工作,我们更加要求学生会vue,react,那怎么办呢?我们便对其进行增强
function Student(){}
Student.prototype.study = function(){console.log('html');console.log('css');console.log('js');
}
// 定义一个装饰类,对student类进行增强
function Decorator(someBody){this.someBody = someBodythis.someBody.ability = 'ability--'return this.someBody
}
var jitao = new Student();
jitao = new Decorator(jitao)
console.log(jitao.ability);
可以看到我们在jitao
这个对象身上增强了一个属性ability
,而且可以看到,jitao
这个属性依旧是Student里面的。
增强方法
上述是增强了一个对象,那么如何增强一个方法呢?
function Student() { }
Student.prototype.study = function () {console.log('html');console.log('css');console.log('js');
}
// 定义一个装饰类,对Student类进行增强
function Decorator(someBody) {this.someBody = someBody// 把之前study方法备份一下this.someBody._study = someBody.study// 把Decorator构造器中生成的对象中的study,覆盖掉之前的study方法this.someBody.study = this.studyreturn this.someBody
}
Decorator.prototype.study = function(){// 调用原本的study方法this._study();console.log('vue');console.log('react');
}
let jitao = new Student();
jitao = new Decorator(jitao)
jitao.study()
- 注意:目前ES中
Decorator
还处于提案阶段,各大浏览器和node,均未公开支持这一特性.如果想要使用,则需要借用babel
的一个插件babel-plugin-transform-decorators
才可以.
结语
js的设计模式是开发中不可或缺的一部分,我们要加强学习,小编学识尚浅,有不足之处,请纰漏
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享