javascript单例模式与策略模式实例详解

 更新时间:2023年06月25日 09:16:32   作者:flying_huixia  
这篇文章主要介绍了javascript单例模式与策略模式,结合实例形式详细分析了javascript单例模式与策略模式基本概念、功能、实现技巧与相关注意事项,需要的朋友可以参考下

一、单例模式

1、概念

保证一个类仅有一个实例,并提供一个访问它的全局访问点

2、单例模式的实现 -- 以创建div节点为例

var createDiv = (function(){
    var instance;
    var createDiv = function(html){
        if(instance){
            return instance
        }
        this.html = html;
        this.init();
        return instance = this;
    };
    createDiv.prototype.init = function(){
         var div = document.createElement('div');
         div.innerHTML = this.html;
         document.body.appendChild(div)
    }    
    return createDiv;    
  })()
var a =new createDiv('one');
var b =new createDiv('two');
console.log(a===b);  //true

上述例子有缺点:

(1)使用了匿名自执行函数,增加了函数复杂度

(2) createDiv函数做了两件事情,一是创建对象,二是管理单例。违背了单一职责原则

改进--》使用代理实现

    //代理模式--改进
        //只负责创建div的一个类
        var createDiv = function (html) {
            this.html = html;
            this.init();
        };
        createDiv.prototype.init = function () {
            var div = document.createElement('div');
            div.innerHTML = this.html;
            document.body.appendChild(div)
        }
        //引入代理类
        var proxySingle = (function(){
            var instance;
            return function(html){
                if(!instance){
                    instance = new createDiv(html)
                }
                return instance  
            }
        })();
        var a = new proxySingle('one');
        var b = new proxySingle('two');
        console.log(a === b); //true

3、惰性单例(使用)

只在需要的时候才创建对象实例

联系登陆功能的需求,登陆的弹框只会出现一次,在点击点击登陆按钮的时候出现

两种实现

(1)在页面加载完成时,创建好这个浮窗,浮窗一开始是隐藏状态,当用户点击登录的时候,它才开始显示。缺点:会白白浪费一些DOM节点。

(2)当用户点击登陆按钮时才开始创建浮窗:代码如下:

var createLoginer = function(){
    var login = document.createElement("div");
    login.innerHTML='登录浮窗';
    login.style.display = 'none';
    document.body.appendChild(login);
    return login
}
//点击登陆按钮
btn.onclick = function(){
   var loginer = createLoginer();
   loginer.style.display = 'block';
}

现在惰性的目的达到了,但失去了单例的效果--》再次修改如下:

用一个变量判断是否已经创建过登录浮窗

 //创建登陆浮窗
        var createLoginer = function () {
            var login = document.createElement("div");
            login.innerHTML = '登录浮窗';
            login.style.display = 'none';
            document.body.appendChild(login);
            return login
        }
        var loginer;
        var getSingle = function (fn) {
            return function () {
                console.log(this)
                return loginer || (loginer = fn.apply(this))
            }
        }
        //createSingleLoginer接下来作为函数调用,所以getSingle得返回一个函数,并且这个函数得返回登录浮窗
        var createSingleLoginer = getSingle(createLoginer);
        //点击登陆按钮
        var btn = document.getElementById("btn");
        btn.onclick = function () {
            var loginer = createSingleLoginer();
            loginer.style.display = 'block';
        }

getSingle就是用来管理单例的 

惰性单例:只有在合适的时候才创建对象,并只创建唯一的一个。把创建对象和管理单例的职责分布在不同的方法中,组合起来才能发挥真正的单例模式的威力。

二、策略模式

1、概念:

定义一系列的算法,把他们一个个封装起来,并且使他们可以相互替换

2、实例

发年终奖,按照等级和各自的基础工资进行乘积运算

  var strage = {
            S:function(salary){
                return salary*4
            },
            A:function(salary){
                return salary*3
            },
            B:function(salary){
                return salary*2
            }
        }
        var calculateBounus = function(level,salary){
            return strage[level](salary)
        };
        console.log(calculateBounus('S',2000)) //8000
        console.log(calculateBounus('A',2000))  //6000

3、策略模式用来封装算法,更广义的使用,表单验证登录算法

把校验方式封装成策略对象

 var validatorFunc = function () {
            var validator = new Validator();
            validator.add(loginForm.userName, "isEmpty", '用户名不能为空')
            validator.add(loginForm.passWord, "minLength:6", '密码长度不能少于6位')
            validator.add(loginForm.phone, "phoneValidator", '手机号码格式错误')
            var errMsg = validator.start();
            return errMsg
        }
        var loginForm = document.getElementById("login")
        function login() {
            var errMsg = validatorFunc();
            if (errMsg) {
                alert(errMsg);
                return false; //阻止表单提交
            }
        }
        var Validator = function () {
            //缓存校验规则
            this.cache = [];
        }
        Validator.prototype.add = function (dom, rule, err) {
            var ary = rule.split(':');
            this.cache.push(function () {
                var strategy = ary.shift();
                ary.unshift(dom.value);
                ary.push(err)
                return loginStrage[strategy].apply(dom, ary)
            })
        }
        Validator.prototype.start = function () {
            for (var i = 0; i < this.cache.length; i++) {
                var err = this.cache[i]()
                if (err) {
                    alert(err)
                }
            }
        }

运行页面:

相关文章

  • JS函数arguments数组获得实际传参数个数的实现方法

    JS函数arguments数组获得实际传参数个数的实现方法

    下面小编就为大家带来一篇JS函数arguments数组获得实际传参数个数的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • javascript实现列表滚动的方法

    javascript实现列表滚动的方法

    这篇文章主要介绍了javascript实现列表滚动的方法,较为详细的分析了javascript实现列表滚动的页面布局及javascript滚动效果的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • 深入浅出JavaScript前端中的设计模式

    深入浅出JavaScript前端中的设计模式

    这篇文章主要介绍了JavaScript前端中的设计模式,设计模式是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结,感兴趣想要详细了解可以参考下文
    2023-05-05
  • js实现随机点名程序

    js实现随机点名程序

    这篇文章主要为大家详细介绍了js实现随机点名程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • 浅析JavaScript中的隐式类型转换

    浅析JavaScript中的隐式类型转换

    在我们学习或者工作中,或多或少会遇到过隐式类型转换,但是为什么会有这种现象?这种现象背后的原理是什么?可能是大多数人没有思考过的,本文就来和大家一起浅析一下
    2023-03-03
  • js正则表达式中exec用法实例

    js正则表达式中exec用法实例

    这篇文章主要介绍了js正则表达式中exec用法,实例分析了javascript中使用exec执行正则表达式的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • 如何在js中引入less的变量

    如何在js中引入less的变量

    这篇文章主要介绍了如何在js中引入less的变量,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • js时间日期和毫秒的相互转换

    js时间日期和毫秒的相互转换

    js时间日期和毫秒的相互转换,需要的朋友可以参考一下
    2013-02-02
  • JavaScript实现点击按钮切换网页背景色的方法

    JavaScript实现点击按钮切换网页背景色的方法

    这篇文章主要介绍了JavaScript实现点击按钮切换网页背景色的方法,涉及JavaScript基于鼠标事件动态操作页面元素样式的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-10-10
  • 解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题

    解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题

    今天小编就为大家分享一篇解决LayUI加上form.render()下拉框和单选以及复选框不出来的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09

最新评论