在了解单例模式之前,我们要先搞懂什么是设计模式:
比较官方的设计模式定义:就是在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案。
当然说白了就是:设计模式对某个特定场景下对某种问题的解决方案。所以,我们在合适的场景下可能会条件反射一样自然而然想到符合这种场景的设计模式。 所有的设计模式的共同目标都是:高内聚,低耦合。
我们在日常的开发当中,都或多或少地接触了设计模式,但是很多时候不知道自己使用了哪种设计模式或者说该使用何种设计模式。其实我个人觉得哈,咱们用不着纠结该用什么样的设计模式,因为有的时候在不经意间我们就已经使用了设计模式当中的一种。
1、首先我们要大概的知道单例模式的概念:
- 单例模式也叫单体模式。
- 核心思想是保证一个类仅有一个实例,并提供一个访问它的全局访问点。
- 实现的方法为先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
- 说白了就是:多次创建同一个对象时,没有必要创建多个对象,只需要一个即可。
2、适用场景:
①如果我们希望p1,p2是完全相等的应该怎样做?
传统代码如下:
function Fn(){
if(!Fn.obj){
Fn.obj = {};
}
Fn.obj.sayHello = "hello";
return Fn.obj;
}
let p1 = new Fn();
let p2 = new Fn();
console.log(p1 === p2); // true
可以在构造函数上创建一个instance变量来保存实例。如果实例存在则直接返回,如果不存在则创建一个保存在instance属性中并返回。
// 首先封装一个构造函数
function Person(){}
// 封装一个单例模式的调用方式
let f = (function(){
let instance;
return function(){
if(!instance){
instance = new Person();
}
return instance;
}
})();
let p1 = f();
let p2 = f();
console.log(p1); // Person
console.log(p2); // Person
console.log(p1 === p2); // true
②我们平时在使用的过程中,肯定还会用到DOM节点,也就是在下面的代码中的init函数中去创建DOM元素,但是这样操作就会导致每次创建实例的时候都创建一次DOM节点,这显然是不正确的,因此,我们可以把DOM的创建过程提到函数顶部,也就是程序一开始直接创建一个DOM节点,仅在init中去修改里面的内容。这样是不是就省了好多事。
function Msg(){
this.ele = document.createElement("div");
document.body.appendChild(this.ele);
}
Msg.prototype.init = function(str){
this.ele.innerHTML = str;
}
let singleCase = (function (){
let instance;
return function(text){
if(!instance){
instance = new Msg();
}
instance.init(text);
return instance;
}
})();
let m1 = singleCase("hello");
let m2 = singleCase("world");
console.log(m1===m2); // true
注意:
当在一个命名空间A中调用别的命名空间B中的函数的时候,调用方法为B.functionName();
当在一个命名空间A中调用自己空间中的函数的时候,调用方法为 this.functionName()。