zoukankan      html  css  js  c++  java
  • JavaScript设计模式之单例模式

    单例模式是javascript中最简单也是最常用的模式之一。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

    单例模式的特点:

    1、单例类只能有一个实例。

    2、单例类必须自己创建自己的唯一实例。

    3、单例类必须给所有其他对象提供这一实例。

    主要解决:一个全局使用的类频繁地创建与销毁。

    怎么方便理解和记忆这种模式呢?

    用一句话来记忆它就是:只有一个实例,有一个访问它的全局访问点,不能与new关键字一起使用。

    那么从最简单的单例模式讲起,在javascript中一个对象字面量可以认为是一个最简单的单例类,以为它符合单例类的特点:只有一个实例,有一个全局访问点。

    示例:

    var Singleton = {
        attribute: true,
                    
        method1: function(){
            //do something
        },
                    
        method2: function(){
            //do something
        },    
    };

    Singleton.name = false;

    上面示例的单例对象可以被修改,你可以随意添加属性和方法到对象中,又或者用delete运算符删除现有的成员。这实质上是违背了面向对象设计的一个原则:类可以被扩展,但不应该被修改。传统意义上的单例模式的定义是:单例类仅有一个实例,并提供一个访问它的全局访问点。上面的对象字面量不是一个实例化的类,所以严格来说,它不属于单例类。javascript不是一门传统的语言,所以不必一定要按传统的定义来限定它,我们将单例模式的定义更广义化:单例类是一组相关的属性和方法的集合,如果它能被实例化,那么它只能被实例化一次。这样对象字面量就符合单例模式的定义了。

    拥有私有成员的单例类:

    现在一个对象字面量就是javascript中最简单的单例类,那怎么实现单例类的私有成员呢?私有成员是对象内部独有的、其他对象无法访问的成员。在javascript中实现私有成员的方法是使用闭包:

    var Singleton = (function(){
                    
        var name = 'singleton';
                    
        function getName(){
            alert(name);
        };
                    
        return {
            attribute: true,
            getName: getName
        }
                    
    })();
                
    Singleton.getName();  //singleton

    上面的单例类实现的name成员的私有化。

    单例的使用很广泛,一个最常见的例子就是网页中的弹框层,比如:登录框、提示框等等。

    单例模式实现网页弹框:

    var createDiv = (function(){
        div = document.createElement("div");
        div.innerHTML = '我是登录框';
        document.body.appendChild(div);
        return div;
    })();

    这种在页面一开始就创建DOM节点的方式有一个问题,也许我们进入一个网站只是随便看看,根本不需要进行登录操作,因为登录浮窗总是一开始就被创建好,那么很有可能将白白浪费一些 DOM节点。

    惰性单例

    惰性单例指的是在需要的时候才创建对象实例。惰性单例是单例模式的重点,这种技术在实
    际开发中非常有用。

    接下来我们使用惰性单例实现弹框,在用户点击登录按钮的时候才创建登录框:

    var createDiv = function(){
        var div;

    return function(){ if(!div){ div = document.createElement("div"); div.innerHTML = '我是登录框'; document.body.appendChild(div); } return div; } }; document.querySelector(".btn").onclick = createDiv();

    通用的惰性单例


    把上面创建div的过程提取出来,便得到一个通用的惰性单例模式:

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

    现在用通用的惰性单例改造下前面登录框的代码:

    var createSingleton = function(fn){
        var singleton;
        
    return function(){ return singleton || (singleton = fn.apply(this, arguments)); } }; function createDiv(){ var div = document.createElement("div"); div.innerHTML = '我是登录框'; document.body.appendChild(div); return div; }; var createDivSingleton = createSingleton(createDiv); document.querySelector(".btn").onclick = function(){ var div = createDivSingleton(); };

    以上登录框应该一开始是隐藏状态的,这里为了能更好的理解单例模式,简化了这些细节。

    单例模式的优缺点:

    优点: 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。 2、避免对资源的多重占用(比如写文件操作)。

    缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

  • 相关阅读:
    kubernetes 将pod运行在某些特定的节点上,给节点打标签
    kubernetes 安装metrics-server
    数组基本内容,如有遗漏还请指出!
    ES6新属性(追加)
    ES6新属性笔记
    Flex 布局教程
    你知道js中的变量你会定义吗?那常量呢?
    ES6-01:常量与变量的声明
    三种方法实现js中类的继承
    JS完成页面跳转并传参的方法|附加:循环遍历对象
  • 原文地址:https://www.cnblogs.com/jofun/p/8504797.html
Copyright © 2011-2022 走看看