专栏首页前端那些事设计模式之单例模式与场景实践

设计模式之单例模式与场景实践

单例介绍

上次总结了设计模式中的module模式,可能没有真真正正的使用在场景中,发现效果并不好,想要使用起来却不那么得心应手,

所以这次我打算换一种方式~~从简单的场景中来看单例模式,

因为JavaScript非常灵活,所以在使用设计模式的时候也带来了很强的灵活性,实现单例的方法也有很多,那就需要我们把握住单例模式的核心。

单例模式介绍:

单例模式是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。

在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象

作用:

  1、模块间通信

  2、系统中某各类的对象只能存在一个

  3、保护自己的属性和方法,保证了所有的对象访问的都是同一个实例

注意事项:

  1、注意this的使用

  2、闭包容易造成内存泄露,不需要的尽快处理等待回收

简单场景

我们先来实现一个标准的单例模式:

  1、如果实例存在就返回,实例不存在就创建新实例;

  2、从全局命名空间中隔离出代码,从而为函数提供单一访问点:

        var mySingleton = (function () {
            // 实例保持Singleton的一个引用
            let instance;

            // Singleton
            // 私有方法和变量
            function init() {
                function privateMethod() {
                    console.log('I am private');
                }
                const privateVariable = ' I am also private ';
                const privateRandomNumber = Math.random();
                // 公有方法和变量
                return {
                    publicMethod:function(){
                        console.log('I am public');
                    },
                    getRandomNumber:function(){
                        return privateRandomNumber; 
                    }
                }
            }

            // 获取Singleton实例,如果存在就返回,不存在就创建新实例
            return {
                getInstance:function(){
                    if(!instance){
                        instance = init();
                    }
                    return instance;
                }
            }

        })();

        // 测试
       const singleA = mySingleton.getInstance();
       const singleB = mySingleton.getInstance();
       console.log( singleA.getRandomNumber() === singleB.getRandomNumber());  // true
       console.log(singleA.publicMethod())  // I am public

下面写一个我们在场景中经常使用的一种简单的非标准的单例模式类型,

场景一:使用简单的单例模式实现一个可编辑表格

html

   <table class="table table-bordered" id="js-table-test">
        <tr>
            <td>编号</td>
            <td>姓名</td>
        </tr>
        <tr>
            <td>1</td>
            <td>okaychen</td>
        </tr>
        <tr>
            <td>2</td>
            <td>StackOverflowChen</td>
        </tr>
    </table>

没使用单例模式之前,我们可能会这样处理:

   $("#js-table-test td").click(function (argument) {
            var m = $(this).html();
            var s = "<input type='text' value='" + m + "'  />";
            $(this).html(s);
        })
        $("#js-table-test td").on('keyup','input',function(e){
            e.stopPropagation();
            var me = $(this);
            if(e.keyCode==13){
                me.val();
            }
        })

那么就让我们对比一下使用单例的代码 思路>>

1、使用自执行函数传递参数$,减少查询次数

2、使用简单的单例模式,为之后修改或者模块化打基础

提供单一访问点init通过datas共享数据,render封装对应的元素,bind来绑定事件,_do来规范私有事件;

  (function ($) {
            // 命名空间
            var index = {
                init: function () {
                    // 入口
                    var me = this;
                    me.render();
                    me.bind();
                },
                datas: {
                    // 共享数据
                    num: 1
                },
                render: function () {
                    // 封装对应的元素
                    var me = this;
                    me.test = $('#js-table-test td');
                },
                bind: function () {
                    // 绑定事件
                    var me = this;
                    me.test.on('click', $.proxy(me['_do'], this));
                },
                _do: function (e) {
                    // 私有事件
                    var me = this;
                    var m = $(e.target).text();
                    var s = "<input type='text' value='" + m + "'  />";
                    $(e.target).html(s);
                    console.log(me.datas.num ++)
                }
            }
            index.init();
        })(jQuery);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • async和enterproxy控制并发数量

    聊聊并发与并行 并发我们经常提及之,不管是web server,app并发无处不在,操作系统中,指一个时间段中几个程序处于已经启动运行到完毕之间,且这几个程序都...

    okaychen
  • JavaScript快速查找节点

    我们在实际的开发中,经常要获取页面中某个html元素,动态更新元素的样式、内容属性等。 ? 我们已经知道在JavaScript中提供下面的方法获取子、父、兄节...

    okaychen
  • 页面重构-让我们的布局自适应

    css重构之旅 >前言: 今年我大一,马上就要大二了。从高三毕业暑假到大学的这一年马上过去,马上迎来大二生活.学习前端也有将近一年了。一昧去追求那些视觉的效果和...

    okaychen
  • 微信(Chrome)漏洞复现与简单分析小结

    2、漏洞复现 这里微信的利用方式与Chrome差不多,就不再详细写具体步骤了,只需要将以下EXP中的第5行shellcode替换为我们CS或MSF生成的3...

    潇湘信安
  • 「小程序JAVA实战」小程序的横向视频和页面拦截(59)

    PS:小程序一般的开发思路就是尽量前端能办的少麻烦后端,减少交互。这样用户体验就上去了。

    IT故事会
  • 树莓派基础实验15:电位器传感器实验

       电位器(Potentiometer)是具有三个引出端、阻值可按某种变化规律调节的电阻元件。电位器通常由电阻体和可移动的电刷组成。当电刷沿电阻体移动时,在输...

    张国平
  • PHPUnit使用笔记

    1.引入composer composer require  phpunit/phpunit 2.编写测试代码 <?php require_once './v...

    苦咖啡
  • iOS-从循环引用看Block

    说明:在block区内已经释放,到self.block()调用时已经被释放,所以值为null。

    Wilbur-L
  • Webassembly初识

    首先,它是一种解释性语言,大神最开始的设计目标用户就是“非专业编程人员和设计师”,避免了非专业人士对编译器了解的需要,解释性语言就是边解释边执行,与编译性语言的...

    CIKEY
  • iOS· UIGestureRecognizer 与UITouch 的 locationInView方法含义区别

    UIGestureRecognizer 与UITouch 都有一个 locationInView: 方法。

    陈满iOS

扫码关注云+社区

领取腾讯云代金券