单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
利弊分析
-
优点:
- 单例模式可以保证内存中只有一个对象,减少了内存的开销。
- 可以避免对资源的多重占用。
- 方便测试,可以通过接口来控制类的实例化。
- 避免对资源的多重占用。
-
缺点:
- 单例模式一般没有接口,扩展比较困难。
- 单点访问,可能会导致模块的耦合。
-
基本的单例模式,就是对象字面量
js
const SingleTon = {
name:"tom",
age"26",
say(){
console.log("hello")
},
eat(){
console.log("rice")
}
}
//访问单例
SingleTon.gender = '男'
SingleTon.say()
划分命名空间
js
var GianCrop = {};
GianCrop.common = {};
GianCrop.errorCodes = {};
GianCrop.pageHandler = {};
使用私有成员
- 方式一:约定
js
GianCrop.dataParse = {
//约定私有成员以_开头
_method1() {},
_method2() {},
_method3() {}
//约定公共成员不以_开头
method1() {},
method2() {},
method3() {}
};
- 方式二:闭包
js
// MyNameSpce.SingleTon = {}
// 闭包单例模式
let MyNameSpce = {};
MyNameSpce.SingleTon = (function () {
return {
name: "tom",
age: 26,
say() {
console.log("hello");
},
eat() {
console.log("rice");
},
};
})();
const name = MyNameSpce.SingleTon.name;
console.log("🚀 ~ name:", name);
增加私有成员
js
let MyNameSpce = {};
MyNameSpce.SingleTon = (function () {
let isFlag = true;
let count = 30;
function getCount() {
return count;
}
return {
name: "tom",
age: 26,
say() {
console.log("hello");
},
eat() {
console.log("rice");
},
getFlag() {
return isFlag;
},
getCount,
};
})();
const { name, getFlag, getCount } = MyNameSpce.SingleTon;
console.log("🚀 ~ name:", name);
console.log("🚀 ~ getFlag:", getFlag());
console.log("🚀 ~ getCount:", getCount());
/**
* 🚀 ~ name: tom
demo05.js:46 🚀 ~ getFlag: true
demo05.js:47 🚀 ~ getCount: 30
*/
惰性单例模式
js
let MyNameSpce1 = {};
MyNameSpce1.SingleTon = (function () {
let singleTon = null;
function init() {
let isFlag = true;
let count = 30;
function getCount() {
return count;
}
console.log("init-----------");
return {
name: "tom",
age: 26,
say() {
console.log("hello");
},
eat() {
console.log("rice");
},
getFlag() {
return isFlag;
},
getCount,
};
}
return {
getInstance() {
if (!singleTon) {
singleTon = init();
}
return singleTon;
},
};
})();
const demo = MyNameSpce1.SingleTon.getInstance();
const demo2 = MyNameSpce1.SingleTon.getInstance();
console.log(demo.name);
console.log(demo2.name);
//调用了两次实例,但是只初始化了一次
/**
*
* 🚀 ~ name: tom
* 🚀 ~ getFlag: true
🚀 ~ getCount: 30
init-----------
tom
tom
*/
分支
js
var SimpleXhrFactory = (function () {
const standard = {
createXhrObjec() {
return new XMLHttpRequest();
},
};
const activeXNew = {
createXhrObject() {
return new ActiveXObject("Microsoft.XMLHTTP");
},
};
const activeOld = {
createXhrObject() {
return new ActiveXObject("Msxml2.XMLHTTP");
},
};
var testObject;
try {
testObject = standard.createXhrObject();
return standard;
} catch (error) {
try {
testObject = activeXNew.createXhrObject();
return activeXNew;
} catch (error) {
try {
testObject = activeOld.createXhrObject();
return activeOld;
} catch (error) {
throw new Error("can't create xhr object");
}
}
}
})();