目的是提高代码可读性、复用性、可扩展性。
单例模式定义为产生一个类的唯一实例。
简易单例(创建一个浮层)
let singleton = () => {
let createMask
return () => {
return createMask || (createMask = document.body.appendChild(document.createElement('div')))
}
}()
// use
singleton() // 执行创建
singleton() // 利用缓存
// 多次调用只会执行一次创建代码
利用闭包内使用外部函数的变量不会被垃圾回收机制回收的特性,可缓存createMask
变量,实现单例模式。
以上实现存在一定缺点,如对createMask
操作变化,需直接修改singleton
,那就毫无复用性可言。
优化如下
let singleton = (fn) => {
let result
return () => {
return result || (result = fn.apply(this, arguments))
}
}
// use
let createMask = singleton(() => {
return document.body.appendChild(document.createElement('div')))
})
真正创建浮层的代码是通过回调函数的方式传入singleton
包装器中,其实这种方式叫桥接模式
。往后会介绍此模式。
简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况。 说的通俗点,就像公司茶水间的饮料机,要咖啡还是牛奶取决于你按哪个按钮。
简单工厂模式在工作中使用十分频繁。比如封装的ajax库,会根据传参确定是调用get
还是post
。
ES5中对new的实现使用到了简单工厂模式
function A(name) {
this.name = name
}
function ObjectFactory() {
let obj = {},
Constructor = Array.prototype.shift.call(arguments)
obj.__proto__ = typeof Constructor.prototype === 'number' ?
Object.prototype :
Constructor.prototype
let ret = Constructor.apply(obj, arguments)
// 返回值取决于传参
return typeof ret === 'object' ? ret : obj
}
let a = ObjectFactory(A, 'Careteen')
alert(a.name) // Careteen
以上代码可知,所谓的new,本身只是一个对象的复制和改写过程,最终具体生成什么是由调用时传参决定。