首页 >> js开发 >> js代码JavaScript设计模式---单例模式详解【四种基本形式】
js代码JavaScript设计模式---单例模式详解【四种基本形式】
发布时间: 2021年1月13日 | 浏览:
| 分类:js开发
本文实例讲述了JavaScript设计模式---单例模式.分享给大家供大家参考,具体如下:单例模式也称为单体模式,其中:1,单体模式用于创建命名空间,将系列关联的属性和方法组织成一个逻辑单元,减少全局变量。
逻辑单元中的代码通过单一的变量进行访问。2,三个特点:
① 该类只有一个实例;
② 该类自行创建该实例,即在该类内部创建自身的实例对象;
③ 向整个系统公开这个实例接口3,单体模式有四种基本形式:第一种,最简单的单体,只被实例化一次
我简记为json对象第一种,最简单的单体,只被实例化一次
我简记为json对象(1)基本结构
var userInfo={//已经自行被实例化 其实是一json对象
name:"测试名称",
dept:"测试PD",
code:"测试PD001",
getName:function () {
return "测试"
}
};
var userInfo={//已经自行被实例化 其实是一json对象
name:"测试名称",
dept:"测试PD",
code:"测试PD001",
getName:function () {
return "测试"
}
};(2)使用方法与json的使用方法一致:使用点 " . "的方式访问
alert(userInfo.getName())
alert(userInfo.getName())单体模式用来划分命名空间,并将一群相关的属性和方法组织到一起的简单介绍:
var comm={};//一个空对象
comm.userInfo={//空对象下的第一个命名空间
name:"命名空间1下的",
code:"001"
}
comm.funcInfo={//空对象下的第二个命名空间
funcName:"命名空间2下的",
code:"002"
}
var comm={};//一个空对象
comm.userInfo={//空对象下的第一个命名空间
name:"命名空间1下的",
code:"001"
}
comm.funcInfo={//空对象下的第二个命名空间
funcName:"命名空间2下的",
code:"002"
}总结:该种方式可以看出对象的变量值不是动态加载的,而且对象没有显示初始化,由此有了第二种单体模式。第二种,具有局部变量的单体第二种,具有局部变量的单体要求:模拟一个使用ajax从数据库加载数据的过程 (1)简单模拟一下ajax过程
//模拟一个Ajax操作
function Ajax() {};//空对象
//静态函数 模拟作为从数据库取值 此处值写死的
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}
//模拟一个Ajax操作
function Ajax() {};//空对象
//静态函数 模拟作为从数据库取值 此处值写死的
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}(2)在最简单的单体中出现了数据不是动态从数据库加载的,而且没有显示实例化对象,此处使用闭包原理解决上述问题
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var userInfo=(function () {
//(1)利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//(2)利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {//由于模拟的ajax中只是简单传递参数,所以第一个参数可以任意
name=n;
code=c;
})
//(3)单体实现私有变量的赋值
return {
name:name,
code:code
}
})()
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var userInfo=(function () {
//(1)利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//(2)利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {//由于模拟的ajax中只是简单传递参数,所以第一个参数可以任意
name=n;
code=c;
})
//(3)单体实现私有变量的赋值
return {
name:name,
code:code
}
})()(3)使用该种方式的单体,不用实例化 可以直接返回一个单体 【因为使用userInfo时,直接return一个单体回来】
alert(userInfo.name);
alert(userInfo.name);总结:(1)优点,灵活(2)弊端:return 单体数据量比较大时,都需要从数据库取数据,每次加载都要执行,会影响程序性能。由于该种方式每次加载都要直接执行,return单体数据量大时会影响呈现的性能,于是有了第三种单体模式。第三种,惰性单体 提供的解决方案为:调方法时才实例化单体,而不是加载时就执行。第三种,惰性单体 提供的解决方案为:调方法时才实例化单体,而不是加载时就执行。于是在第二种的基础上进行修改为,(1)模拟ajax从数据库加载数据不变
//模拟一个Ajax操作
function Ajax() {}
//静态函数 模拟作为从数据库取值
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}
//模拟一个Ajax操作
function Ajax() {}
//静态函数 模拟作为从数据库取值
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}(2)动态从数据库加载数据 ,显示实例化,使用一个函数(Init())封装产生单体的函数,通过一个私有变量来返回函数(Init())
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var UserInfo=(function () {
var userInfo="";//私有变量
function Init() {//在产生单体方式为包裹一层初始化函数
//利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {
name=n;
code=c;
})
//单体
return {
name:name,
code:code,
}
}
return {//此时开始调用初始化函数实现单体的产生
getInstance:function () {
if(userInfo){//userInfo=""为false
return userInfo;
}else {
userInfo=Init();
return userInfo;
}
}
}
})()
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var UserInfo=(function () {
var userInfo="";//私有变量
function Init() {//在产生单体方式为包裹一层初始化函数
//利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {
name=n;
code=c;
})
//单体
return {
name:name,
code:code,
}
}
return {//此时开始调用初始化函数实现单体的产生
getInstance:function () {
if(userInfo){//userInfo=""为false
return userInfo;
}else {
userInfo=Init();
return userInfo;
}
}
}
})()(3)使用
访问UserInfo对象里面的获取初始化获取对象的函数(getInstance())
alert(UserInfo.getInstance().name);
alert(UserInfo.getInstance().name);总结:使用惰性单体实质上是通过对产生单体的函数进行再一次封装(使用函数封装),再在通过该类提供的唯一接口(getInstance()方法)访问初始化单体 的函数。第四种,分支单体第四种,分支单体简单的用处:做Ajax的时候根据不同的浏览器获得不同的XHR。(将浏览器之间的差异封装到动态方法,适用于解决浏览器之间的差异。)比如下面一个简单的例子:在电脑不同分辨率的情况下初始化不一样的界面。(这里只是弹窗显示而已)(1)获取电脑的分辨率
//得到机器的分辨率
var screenWidth=window.screen.width;//width
var screenHeight=window.screen.height;//height
//得到机器的分辨率
var screenWidth=window.screen.width;//width
var screenHeight=window.screen.height;//height(2)进行分支判断处理 ,将差异封装到动态方法中
var portalInfo=(function () {
//单体
var $1280_1024={info:'1,2,3,5'}//单体1
var $1366_768={info:'4,2,1,2'}//单体2
//动态图选择浏览器的差异结果(这里是分辨率)
if(screenWidth==1280){
return $1280_1024;//返回单体进行初始化
}else if(screenWidth==1366){
return $1366_768;//返回单体进行初始化
}else {
throw new Error("请检查你当前的电脑分辨率")
}
})();
var portalInfo=(function () {
//单体
var $1280_1024={info:'1,2,3,5'}//单体1
var $1366_768={info:'4,2,1,2'}//单体2
//动态图选择浏览器的差异结果(这里是分辨率)
if(screenWidth==1280){
return $1280_1024;//返回单体进行初始化
}else if(screenWidth==1366){
return $1366_768;//返回单体进行初始化
}else {
throw new Error("请检查你当前的电脑分辨率")
}
})();(3)使用 ,获取最终的结果
alert(portalInfo.info)//我的结果为4,2,1,2 这是由于我的电脑的分辨率为1366*768
alert(portalInfo.info)//我的结果为4,2,1,2 这是由于我的电脑的分辨率为1366*768总结一下,对于分支单体有一个缺点:分支中,单体1和单体2都被创建了,并保存在内存中了,但只用到一个。需要在 计算时间 和 占用内存 两者中取舍。需要在 计算时间 和 占用内存 两者中取舍。感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools./code/HtmlJsRun测试上述代码运行效果。在线HTML/CSS/JavaScript代码运行工具在线HTML/CSS/JavaScript代码运行工具http://tools./code/HtmlJsRun关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》javascript面向对象入门教程JavaScript错误与调试技巧总结JavaScript数据结构与算法技巧总结JavaScript遍历算法与技巧总结JavaScript数学运算用法总结希望本文所述对大家JavaScript程序设计有所帮助。
逻辑单元中的代码通过单一的变量进行访问。2,三个特点:
① 该类只有一个实例;
② 该类自行创建该实例,即在该类内部创建自身的实例对象;
③ 向整个系统公开这个实例接口3,单体模式有四种基本形式:第一种,最简单的单体,只被实例化一次
我简记为json对象第一种,最简单的单体,只被实例化一次
我简记为json对象(1)基本结构
var userInfo={//已经自行被实例化 其实是一json对象
name:"测试名称",
dept:"测试PD",
code:"测试PD001",
getName:function () {
return "测试"
}
};
var userInfo={//已经自行被实例化 其实是一json对象
name:"测试名称",
dept:"测试PD",
code:"测试PD001",
getName:function () {
return "测试"
}
};(2)使用方法与json的使用方法一致:使用点 " . "的方式访问
alert(userInfo.getName())
alert(userInfo.getName())单体模式用来划分命名空间,并将一群相关的属性和方法组织到一起的简单介绍:
var comm={};//一个空对象
comm.userInfo={//空对象下的第一个命名空间
name:"命名空间1下的",
code:"001"
}
comm.funcInfo={//空对象下的第二个命名空间
funcName:"命名空间2下的",
code:"002"
}
var comm={};//一个空对象
comm.userInfo={//空对象下的第一个命名空间
name:"命名空间1下的",
code:"001"
}
comm.funcInfo={//空对象下的第二个命名空间
funcName:"命名空间2下的",
code:"002"
}总结:该种方式可以看出对象的变量值不是动态加载的,而且对象没有显示初始化,由此有了第二种单体模式。第二种,具有局部变量的单体第二种,具有局部变量的单体要求:模拟一个使用ajax从数据库加载数据的过程 (1)简单模拟一下ajax过程
//模拟一个Ajax操作
function Ajax() {};//空对象
//静态函数 模拟作为从数据库取值 此处值写死的
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}
//模拟一个Ajax操作
function Ajax() {};//空对象
//静态函数 模拟作为从数据库取值 此处值写死的
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}(2)在最简单的单体中出现了数据不是动态从数据库加载的,而且没有显示实例化对象,此处使用闭包原理解决上述问题
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var userInfo=(function () {
//(1)利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//(2)利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {//由于模拟的ajax中只是简单传递参数,所以第一个参数可以任意
name=n;
code=c;
})
//(3)单体实现私有变量的赋值
return {
name:name,
code:code
}
})()
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var userInfo=(function () {
//(1)利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//(2)利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {//由于模拟的ajax中只是简单传递参数,所以第一个参数可以任意
name=n;
code=c;
})
//(3)单体实现私有变量的赋值
return {
name:name,
code:code
}
})()(3)使用该种方式的单体,不用实例化 可以直接返回一个单体 【因为使用userInfo时,直接return一个单体回来】
alert(userInfo.name);
alert(userInfo.name);总结:(1)优点,灵活(2)弊端:return 单体数据量比较大时,都需要从数据库取数据,每次加载都要执行,会影响程序性能。由于该种方式每次加载都要直接执行,return单体数据量大时会影响呈现的性能,于是有了第三种单体模式。第三种,惰性单体 提供的解决方案为:调方法时才实例化单体,而不是加载时就执行。第三种,惰性单体 提供的解决方案为:调方法时才实例化单体,而不是加载时就执行。于是在第二种的基础上进行修改为,(1)模拟ajax从数据库加载数据不变
//模拟一个Ajax操作
function Ajax() {}
//静态函数 模拟作为从数据库取值
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}
//模拟一个Ajax操作
function Ajax() {}
//静态函数 模拟作为从数据库取值
Ajax.request=function (url,fn) {
//默认永远回调成功
if(true){
fn("测试值1","测试值2")
}
}(2)动态从数据库加载数据 ,显示实例化,使用一个函数(Init())封装产生单体的函数,通过一个私有变量来返回函数(Init())
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var UserInfo=(function () {
var userInfo="";//私有变量
function Init() {//在产生单体方式为包裹一层初始化函数
//利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {
name=n;
code=c;
})
//单体
return {
name:name,
code:code,
}
}
return {//此时开始调用初始化函数实现单体的产生
getInstance:function () {
if(userInfo){//userInfo=""为false
return userInfo;
}else {
userInfo=Init();
return userInfo;
}
}
}
})()
//使用闭包的原理解决:动态从数据库加载数据 ,显示实例化
var UserInfo=(function () {
var userInfo="";//私有变量
function Init() {//在产生单体方式为包裹一层初始化函数
//利用闭包使单体有自己的私有局部变量
var name="";
var code="";
//利用ajax访问数据库取到数据
Ajax.request("url",function (n,c) {
name=n;
code=c;
})
//单体
return {
name:name,
code:code,
}
}
return {//此时开始调用初始化函数实现单体的产生
getInstance:function () {
if(userInfo){//userInfo=""为false
return userInfo;
}else {
userInfo=Init();
return userInfo;
}
}
}
})()(3)使用
访问UserInfo对象里面的获取初始化获取对象的函数(getInstance())
alert(UserInfo.getInstance().name);
alert(UserInfo.getInstance().name);总结:使用惰性单体实质上是通过对产生单体的函数进行再一次封装(使用函数封装),再在通过该类提供的唯一接口(getInstance()方法)访问初始化单体 的函数。第四种,分支单体第四种,分支单体简单的用处:做Ajax的时候根据不同的浏览器获得不同的XHR。(将浏览器之间的差异封装到动态方法,适用于解决浏览器之间的差异。)比如下面一个简单的例子:在电脑不同分辨率的情况下初始化不一样的界面。(这里只是弹窗显示而已)(1)获取电脑的分辨率
//得到机器的分辨率
var screenWidth=window.screen.width;//width
var screenHeight=window.screen.height;//height
//得到机器的分辨率
var screenWidth=window.screen.width;//width
var screenHeight=window.screen.height;//height(2)进行分支判断处理 ,将差异封装到动态方法中
var portalInfo=(function () {
//单体
var $1280_1024={info:'1,2,3,5'}//单体1
var $1366_768={info:'4,2,1,2'}//单体2
//动态图选择浏览器的差异结果(这里是分辨率)
if(screenWidth==1280){
return $1280_1024;//返回单体进行初始化
}else if(screenWidth==1366){
return $1366_768;//返回单体进行初始化
}else {
throw new Error("请检查你当前的电脑分辨率")
}
})();
var portalInfo=(function () {
//单体
var $1280_1024={info:'1,2,3,5'}//单体1
var $1366_768={info:'4,2,1,2'}//单体2
//动态图选择浏览器的差异结果(这里是分辨率)
if(screenWidth==1280){
return $1280_1024;//返回单体进行初始化
}else if(screenWidth==1366){
return $1366_768;//返回单体进行初始化
}else {
throw new Error("请检查你当前的电脑分辨率")
}
})();(3)使用 ,获取最终的结果
alert(portalInfo.info)//我的结果为4,2,1,2 这是由于我的电脑的分辨率为1366*768
alert(portalInfo.info)//我的结果为4,2,1,2 这是由于我的电脑的分辨率为1366*768总结一下,对于分支单体有一个缺点:分支中,单体1和单体2都被创建了,并保存在内存中了,但只用到一个。需要在 计算时间 和 占用内存 两者中取舍。需要在 计算时间 和 占用内存 两者中取舍。感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools./code/HtmlJsRun测试上述代码运行效果。在线HTML/CSS/JavaScript代码运行工具在线HTML/CSS/JavaScript代码运行工具http://tools./code/HtmlJsRun关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》javascript面向对象入门教程JavaScript错误与调试技巧总结JavaScript数据结构与算法技巧总结JavaScript遍历算法与技巧总结JavaScript数学运算用法总结希望本文所述对大家JavaScript程序设计有所帮助。
相关文章:
- js关于angular浏览器兼容性问题的解决方案js大全
- JavaScript通过实例解析vuejs如何实现调试代码
- jsvuex中store存储store.commit和store.dispatch的用法js大全
- jsvue+axios全局添加请求头和参数操作js大全
- jsvue data对象重新赋值无效(未更改)的解决方式js大全
- jsVUE项目axios请求头更改Content-Type操作js大全
- jsVue-CLI 3 scp2自动部署项目至服务器的方法js大全
- JavaScript深入了解Vue.js 混入(mixins)
- JavaScriptthree.js欧拉角和四元数的使用方法
- js解决VUE自定义拖拽指令时 onmouseup 与 click事件冲突问题js大全