javascript实现单例模式

242 阅读3分钟

什么是单例模式

这是我参与更文挑战的第2天,活动详情查看更文挑战

单例模式也被称为单体模式,是只允许实例化一次的对象类。有时我们也会用一个对象来规划一个命名空间井井有条的管理对象上属性和方法。这可能是javascript里面最常见的一种模式了。例如我们以前使用过的jquery、loadash

主要解决什么问题

例如我们在活动页面实现新闻列表的鼠标滑动特效,假如实现的方式是这样的:

function getId(id) {
    return document.getElementById(id);
}
function setCss(id, key, value) {
    getId(id).style[key] = value;
}
function attr(id, key, value) {
    getId(id)[key] = value;
}
function setInnerHtml(id, value) {
    getId(id).innerHTML = value;
}
function setEvent(id, type, fn) {
    getId(id)["on" + type] = fn;
}

大家看出这样定义有什么缺点没?

  1. 首先定义了好几个函数,相当于是定义了好几个变量,变量是需要占用系统空间的
  2. 这里面定义了很多变量,如果日后其他人需要为你的页面添加新的需求,新定义的方法可能重名,就会和你定义的方法起冲突 单例模式主要解决的问题就是:避免频繁的创建和销毁变量或者实例

单例模式的优点:

内存中只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如说是首页页面的缓存)

单例模式的使用场景

实现一个登录的弹窗

需求:页面中有三个子功能,都是需要登陆后才能进入的,如果用户没有登陆的话,点击这些功能就会弹出登陆提示框

分析:

  1. 首先,我们这三个功能都是点击后才能查看的,所以,这三个元素肯定是有个点击时间onclick
  2. 三个部分都是判断登陆与否,没登陆的话就是弹出登陆的弹框。那么弹框是三次都是同样的,这个应该不难理解吧。我们点击的时候会创建dom元素,生成弹窗。那么三次的都是一样的,那我们就没有必要创建三次,只要创建一次就可以了,然后把它缓存起来,然后第二次点击的时候就判断一下缓存中时候存在,如果存在的话,就直接用缓存的就好了 注意点:此处涉及到闭包,闭包的作用之一就是能缓存。这块知识点不了解的可自行去补充这块的知识
// 创建登录框的职责
function  createEle(str,b,c) {
    var myDiv = document.createElement('div')
    myDiv.innerHTML = '登录成功'
    myDiv.style.display = 'none'
    document.body.append(myDiv)
    return myDiv
}
// 单例的职责
// 使用闭包,把生成的dom缓存起来
function getSingle(fn){
    var result
    return function() {
        // 判断dom元素是否存在,存在的就使用当前的,不存在的话就创建
        return result || (result = fn.call(this,arguments))
    }
}
var createLogin = getSingle(createEle)
document.getElementById('login').onclick = function name(params) {
    var loginLayer = createLogin()
    loginLayer.style.display = 'block'
    console.log(loginLayer)
}