JavaScript单例模式能不能去实例只留单原理解析

 更新时间:2022年12月22日 09:41:44   作者:qb  
这篇文章主要为大家介绍了JavaScript单例模式能不能去实例只留单原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一、单例模式的分类

一个环境中有且只有一个实例,并且当前环境可以访问到它。往小了说,当前环境可以是一个函数作用域、块级作用域,往大了说可以是全局window或者global环境。如果按照实例的创建时机进行单例模式的分类,有:

  • 普通单例模式:在环境初始时就创建
  • 惰性单例模式:在某个特定的时机才创建

二、惰性单例模式

从单例模式的定义出发,一个环境中有且只有一个实例,并且使用时才去创建它,那么就可以把当前单例模式称之为惰性单例模式

  • 惰性,指的是只有在使用的时候才去创建
  • 单例,指的是当前环境有且只有单一的一个实例

弹窗案例:在页面打开的时候,页面中有登录按钮,在点击时,需要创建一个dom节点。
(1)首先,实现一个功能函数:创建节点的函数

var domFun = function () {
    var dom = document.createElement('div');
    dom.innerHTML = '登录窗口demo'
    dom.style.display = 'none';
    document.body.appendChild(dom);
    return dom;
}

(2)其次,创建管理单例的函数

var createSingle = function (fn) {
    var result;
    return function () {
        return result || (result = fn.apply(this, arguments));
    }
}

采用闭包的形式,让result变量在当前环境不销毁,如果该变量已经存在,直接返回,如果没有,让当前环境调用fn功能函数,并赋值给result。该过程保证了当前环境只有一个实例。
(3)将创建节点的函数和管理单例的函数糅合

var createSingleDom = createSingle(domFun)

(4)最后,在点击按钮的时候,进行实例的创建

var loginBtn = document.querySelector('.login')
loginBtn.onclick = function () {
    var loginDom = createSingleDom()
    console.log(loginDom)
    loginDom.style.display = 'block'
}

该过程实现了只有在点击登录按钮的时候才创建节点,是惰性的。

整个过程,将创建惰性实例的过程进行了分解,更易于修改和维护,如果,创建的不是div节点,而是,image图片、iframe嵌套网页、倒计时等其他内容,只需要替换步骤(1)中的内容即可。

这里的例子,我们严格的强调一个实例的事儿。

二、普通单例模式

在vue中的应用:我们知道vue是一个渐进式框架,主要实现视图的渲染,其他的功能可以可以通过第三方插件按需引入,比如路由插件vue-router和全局状态管理vuex

  • 路由vue-router的使用
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
  • 状态vuex的使用
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

vue通过Vue.use(Vuex)的方式进行vue-routervuex的安装,Vue.use的代码如下:

Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }
    // 去掉参数列表中的第一个
    const args = toArray(arguments, 1)
    // 将Vue作为this推入到参数的首位
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
}

可以看出,首次执行vue.use(xxx)的时候,会将该插件推入到数组installedPlugins中去,再次执行vue.use(xxx)的时候,installedPlugins.indexOf(plugin) > -1true,则终止后续逻辑的执行。也就说,vue.use(xxx)只会让该插件执行一次install的安装。

再看 const installedPlugins = (this._installedPlugins || (this._installedPlugins = [])),是不是发现,这里也是单例模式的影子,当this._installedPlugins不存在时为其赋值为[],当前存在时直接返回。

单例模式,去掉具体的例,就剩单模式。就像当前例子中,install只执行一次,this._installedPlugins只初始化一次一样,就体现了一个单字。那这算不算单(例)模式呢?

总结

单例模式是不是可以去实例,只留单呢?这样,很多只执行一次的逻辑也就和单例模式能搭上关系了。仁者见仁智者见智,能不能去,纯属个人想法。因为,优秀的单例模式,是经过无数的程序案例得出的经验性汇总。

以上就是JavaScript单例模式能不能去实例只留单原理解析的详细内容,更多关于JavaScript单例模式去实例的资料请关注脚本之家其它相关文章!

相关文章

  • 微信小程序 封装http请求实例详解

    微信小程序 封装http请求实例详解

    这篇文章主要介绍了微信小程序 封装http请求实例详解的相关资料,需要的朋友可以参考下
    2017-01-01
  • 一文详解Electron 快捷键使用技巧及示例

    一文详解Electron 快捷键使用技巧及示例

    这篇文章主要为大家介绍了Electron 中的快捷键使用技巧及示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • js解决移动端滚动穿透问题方案详解

    js解决移动端滚动穿透问题方案详解

    这篇文章主要为大家介绍了js解决移动端滚动穿透问题方案详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • JavaScript的模块化开发框架Sea.js上手指南

    JavaScript的模块化开发框架Sea.js上手指南

    Sea.js的目的是追求简单的代码书写和组织方式,Sea.js并没有过多功能而是主要对前端程序的部署结构作出约束,下面我们就来看一下JavaScript的模块化开发框架Sea.js上手指南:
    2016-05-05
  • 微信小程序点击控件修改样式实例详解

    微信小程序点击控件修改样式实例详解

    这篇文章主要介绍了 微信小程序点击控件修改样式实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • JS前端画布与组件元信息数据流示例详解

    JS前端画布与组件元信息数据流示例详解

    这篇文章主要为大家介绍了JS前端画布与组件元信息数据流示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • 微信小程序 解析网页内容详解及实例

    微信小程序 解析网页内容详解及实例

    这篇文章主要介绍了微信小程序 解析网页内容详解及实例的相关资料,这里使用爬虫对复杂的网页进行抓取,遇到些问题,这里整理下并解决,需要的朋友可以参考下
    2017-02-02
  • 微信小程序 生命周期函数详解

    微信小程序 生命周期函数详解

    这篇文章主要介绍了微信小程序 生命周期函数的相关资料,需要的朋友可以参考下
    2017-05-05
  • rollup打包引发对JS模块循环引用思考

    rollup打包引发对JS模块循环引用思考

    这篇文章主要为大家介绍了rollup打包引发的对JS模块循环引用的思考,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • JavaScript实现放大镜详细

    JavaScript实现放大镜详细

    这篇文章主要介绍了js实现放大镜,借助宽高等比例放大的两张图片,结合js中鼠标偏移量、元素偏移量、元素自身宽高等属性完成;左侧遮罩移动Xpx,右侧大图移动X*倍数px,具体内容请需要的小伙伴出差下面文章内容
    2021-12-12

最新评论