JavaScript设计模式之单例模式

设计模式开篇
日常开发中,我们都很注重开发技巧,好的开发 技巧可以事半功倍得解决此刻得问题。
那么这些技巧如何来得呢?
我的理解: 经过不断踩坑,解BUG,总结出来一些处理对应问题解决方案,这就所谓的 。
说起设计模式,其实我们日常开始中也经常用到,只是你不知道用的对应的.
学习设计模式的作用
在软件设计中,模式是一些经过了大量实际项目验证的优秀解决方案。熟悉这些模式的程序员,对某些模式的理解也会自然的形成条件反射。当遇到合适的场景出现时,可以快速找到对应的模式来处理当前的问题。
单例模式
定义: 保证 类 仅有 ,并可以全局访问这个.
不是 单例模式,但是在JavaScript 中, 我们经常把单例模式当作全局变量使用。
因为它满足单例模式的两点:
创建的全局变量是独一无二的
它可以全局访问这个变量实例
// login.js
var loginInfo = {
username: '',
token: '',
.......
}
//login.vue
import logins from './login.js'
logins.name = this.username
但是它也有缺点,容易造成命名空间污染。
定义的, 会覆盖掉之前定义的,这样会造成不必要的.
如何处理命名空间污染呢?
如何处理呢?
1.使用命名空间
2.使用闭包封装私有变量
命名空间
对象自变量的形式:
// login.js
export default var loginInfo = {
names:'' ,
token: '',
setName: function (name) {
this.names = name
},
getName: function () {
return this.name
}
}
//login.vue
import logins from './login.js'
logins.token = this.token
使用闭包封装私有变量
把一些变量封装在闭包内部,只暴露一些接口跟外界通信。
外界是访问不到 内部定义的私有变量的,这样就避免了全局命令污染。
var user = (function () {
//外界是访问不了 _name _age
var _name = '张三',
_age = 22;
return {
//这块留给外界通信用
getUserInfo: function () {
console.log(`姓名为:${_name},年龄为:${_age}`)
}
}
})()
user.getUserInfo()
通用的惰性单例模式
在该执行的情况下,执行操作步骤 / .
优点: 节约了性能。
场景1
有时候,例如登陆弹窗,在加载首页的同时,它会渲染这个页的全部,如果首页DOM 内容多,加载速度也会相应的很慢,有很多不需要DOM提前渲染。
这时,可以通过惰性单例模式来解决此问题,例如单击了登陆按钮,才会创建登陆弹窗的DOM,并且记录此次点击状态,如果下次还要打开,只是更改 DOM 的 的 属性即可。 这样节约了首页加载时间,提升页面性能。
// 定义全局通用单例模式
var getSingle = function (fn) {
var result;
return function () {
return result || (result = fn.apply(this, arguments));
}
}
// 创建登陆窗口
var createLoginLayer = function() {
var div = document.createElement('div')
div.innerHTML = '登陆框'
div.style.display = 'none'
document.body.appendChild(div)
return div
}
// 创建单例模式 登陆框
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('btn').onclick = () => {
// 获取单例模式中 返回得登陆框
var loginLayer = createSingleLoginLayer();
// 改变样式
loginLayer.style.display = 'block'
}
场景2
创建唯一的 用于加载第三方页面
var createSingleIframe = getSingle( function() {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe)
return iframe
})
document.getElementById('redirect').onclick = () => {
var iframeLayer = createSingleIframe();
iframeLayer.src = 'http://www.baidu.com'
}
策略模式
定义:
定义一些列的算法,把它们一个个封装起来,留给外界变动的通信参数,相互替换使用。
一个基于策略模式的程序最少由两部分组成:
策略类, 用来封装具体算法,并负责具体计算过程。
环境类, 用来接收用户请求参数,然后将请求参数交给策略类来计算实现
在JavaScript 实现策略模式
需求1
例如:
商店里最近有打折优惠活动,但是这个价格不唯一,打折优惠唯一。(这个可以封装成 ,用来计算价格)
结算价格,需要将 和 传递给 来实现计算。 (一般是通过获取,这里为了演示。这个可以理解成)
使用策略模式
var shopCar = {
'Nike': function( price ) {
return price * 0.4
},
'LiNing': function ( price ) {
return price * 0.6
},
'AnTa': function ( price ) {
return price * 0.6
}
}
var balance = function(kind,price) {
return shopCar[kind](price)
}
console.log(`Nike鞋子价格为${balance('Nike',2000)}`)
//Nike鞋子价格为800
console.log(`LiNing T短袖价格为${balance('LiNing',300)}`)
//LiNing T短袖价格为180
你可能会这样写
这样倒是也可以计算出最终结果。
但它包含了大量的 语句,这些语句覆盖了所有的逻辑分支。
算法复用性差
函数缺乏弹性
var shop = (kind,price) => {
if ( kind == 'Nike') {
return price * 0.4
}
if ( kind == 'LiNing') {
return price * 0.6
}
if ( kind == 'AnTa') {
return price * 0.6
}
}
console.log(shop('LiNing',3000))
结语
❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创作更好的文章