JavaScript-设计模式(一) 单例模式
单例模式定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点
单例模式 是一种常用的模式 ,有一些对象我们往往只需要有一个,比如 全局缓存 、 浏览器的window对象
核心:确保只有一个实例 并提供全局访问
使用场景:登录浮窗、广告弹窗
ES6 实现简单的单例模式:
//单例模式 使实例化对象始终如一
let obj = null//obj不能暴露给被人用 此时还需要继续改进
let Fn = class {
constructor() {
//obj存在 直接返回该对象
if (obj) {
return obj
}
//obj不存在 让obj存储当前的this
obj = this//此时的this就是这个实例化对象
this.x = 10
console.log("构造函数内", this);
}
log() {
console.log(this.x);
}
}
案例 : ES6实现一个简单的 qq 登录框 的单例
css:
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
.login_box{
position: relative;
width: 100%;
height: 100vh;
}
.login_box form {
width: 300px;
border: 1px solid #ddd;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: space-around;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
border-radius: 5px;
}
.login_box h4{
text-align: center;
margin-bottom: 10px;
font-size: 30px;
font-weight: 100;
}
.login_box .from_item{
height: 50px;
width: 100%;
padding: 5px;
text-align: center;
}
.login_box .from_item input{
width: 100%;
height: 100%;
outline: none;
cursor: pointer;
color: #666;
}
.login_box .from_item input[type='text']{
border: none;
border-bottom:1px solid #ddd ;
}
.login_box .from_item input[type='button']{
background: transparent;
color:#000;
border: 1px solid #ddd;
}
.login_box .from_item input[type='button']:hover{
background: rgba(0,0,0,.05);
}
html:
<button id="btn1">QQ- 开启</button>
<button id="btn2">QQ- 关闭</button>
js:
let LoginBox = (function () {
let instance = null
return class {
constructor() {
// 如果实例存在 这个时候只需要修改 当前实例信息 return 出去即可
if (instance) {
return instance
}
// this 指向 instance 实例
instance = this
// 创建登录框
this.ele = document.createElement('div')
this.ele.className = 'login_box'
let item_box = Array.from(new Array(3))
// 创建from表单
let form = document.createElement('form')
// 添加标题
let title = document.createElement('h4')
title.innerText = '登录'
form.appendChild(title)
item_box.forEach((item, index, arr) => {
arr[index] = document.createElement('div')
let input = document.createElement('input')
arr[index].className = 'from_item'
if(index<2){
(index===0)&&(input.placeholder='请输入您的用户名');
(index===1)&&(input.placeholder='请输入您的密码');
input.type='text'
}else{
input.type='button'
input.value='登录'
}
arr[index].appendChild(input)
form.appendChild(arr[index])
})
console.log(item_box)
// 第一个 input 让其为登录框
this.ele.appendChild(form)
}
show() {
document.body.appendChild(this.ele)
document.body.offsetLeft//这是一个连贯性的动作 要让其不连贯 需要触发一次浏览器的ofc 否则无法实现
this.ele.style.display='block'
}
close() {
this.ele.style.display='none'
}
}
})()
let btn1 = document.querySelector('#btn1')
let btn2 = document.querySelector('#btn2')
btn1.onclick = function () {
new LoginBox().show() // 开启登录框
}
btn2.onclick = function () {
new LoginBox().close() // 关闭登录框
}
// test
let p1 = new LoginBox()
let p2 = new LoginBox()
console.log(p1===p2) // true