• Javascript设计模式记录


    prototype与面向对象取舍

    使用prototype原型继承和使用面向对象,都可以实现闭包的效果。那么这两个的选择点,就是方法会不会产生多个实例

    例如,我们需要做一个闭包数组,并给他提供一个添加方法。

    这两种写法都可以实现闭包,但是面向对象的写法,只能存在一个。我们无法对他进行初始化,而原型继承写法,我们则可以对他进行初始化操作。

    所以,当我们这个方法,在整个程序中,是唯一的存在。我们可以使用面向对象的写法,如果可以存在多个,则使用prototype这种写法。

    !(function () {
        //原型继承写法
        var Validator = function(){
            this.cache = [];
        };
        Validator.prototype.add = function(item){
            this.cache.push(item);
        };
        var validator = new Validator(),validatorr = new Validator();
        validator.add("test1"); console.log(validator.cache);
        validatorr.add("test2"); console.log(validatorr.cache);
        //面向对象写法
        var Validator2 = {
            cache : [],
            add : function(item){
                this.cache.push(item);
            }
        };
        Validator2.add("test3"); console.log(Validator2.cache);
        Validator2.add("test4"); console.log(Validator2.cache);
    })()

    调用父类构造函数

    继承关系的两个对象,在实例的过程中,可以通过修改指向,来调整调用构造函数

    !(function () {
        var A = function (light) {
            this.light1 = light;
        };
        var B = function (light) {
            this.light = light;
            A.apply(this,arguments);//你需要手动调用A的构造方法
        };
        //给B赋值的同时,给A赋值
        B.prototype = new A();
        var C = new B(123);
        console.log(C.light);
        console.log(C.light1);
    })()

    单例模式

    保证一个类仅有一个实例,并提供一个访问它的全局访问点。例如:线程池,全局缓存,登录浮窗。

    首先我们需要把单例的逻辑代码单独提取,然后使用惰性单例的方式,也就是返回方法。只有在点击的时候,才会进行执行。

    javascript的单例,跟类不一样。无需创建多余的构造函数这些,直接创建全局变量即可。

    !(function () {
        //管理单例的逻辑代码,如果没有数据则创建,有数据则返回
       var getSingle = function(fn){ //参数为创建对象的方法
           var result;
           return function(){ //判断是Null或赋值
               return result || (result = fn.apply(this,arguments));
           };
       };
        //创建登录窗口方法
        var createLoginLayer = function(){
            var div = document.createElement('div');
            div.innerHTML = '我是登录浮窗';
            div.style.display = 'none';
            document.body.appendChild(div);
            return div;
        };
        //单例方法
        var createSingleLoginLayer = getSingle(createLoginLayer);
    
        //使用惰性单例,进行创建
        document.getElementById('loginBtn').onclick = function(){
            var loginLayer = createSingleLoginLayer();
            loginLayer.style.display = 'block';
        };
    })()
    
    单例模式
    View Code

    策略模式

    定义一系列的算法,把它们一个一个封装起来。将算法的使用与算法的实现分离开来。

    javascript的策略模式很简单,把算法直接定义成函数即可。

    策略模式的优点与缺点

    1. 有效的避免许多重复的复制粘贴作业。
    2. 开闭原则的完美支持,算法完全独立易于切换、理解、拓展。
    3. 算法复用性强
    4. 使用组合和委托让Validator类拥有执行算法的能力,也是继承的一种轻便替代方式

    缺点

    1. 会增加许多策略类或策略对象。
    2. 违反迪米特法则,会将strategy暴露给客户所有实现。
    !(function () {
        //定义算法方法
        var strategies = {
            "S":function(salary){
              return salary * 4;
            },
            "A":function(salary){
                return salary * 3;
            },
            "B":function(salary){
                return salary * 2;
            }
        };
        //执行算法
        var calculateBouns = function(level,salary){
          return strategies[level](salary);
        };
        console.log(calculateBouns('S',2000));
    })() 
    View Code

    undefined终止循环

    (写具体代码之前,先记录一个知识点)。当循环表达式为undefined时,循环会终止

    !(function(){
        var cale = [1,2,3];
        for(var i= 0,validate;validate=cale[i];)
        {
            cale.shift();
            console.log(validate);
        }
    })() //1,2,3
    View Code

    观察者模式

    定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

    例如事件绑定,就是一个标准的观察者模式

    document.body.addEventListener('click',function(){
           console.log(2);
        },false);
        document.body.click();
    View Code

    命令模式

    命令模式指的是一个执行某些特定事情的指令。常见的应用场景是:有时候需要向对象发送请求,但不知道接受者是谁,也不知道请求的操作是什么。

    例如:订餐,客人需要给厨师发送请求,至于那个厨师做,做的步骤。客人不知道。这就是命令模式。

    //定义命令模式执行
        var setCommand = function (button, func) {
            button.onclick = function () {
                func.execute();
            };
        };
        var MenuBar = {
            refresh: function () {
                console.log("刷新页面");
            }
        };
        var RefreshMenuBarCommand = function (receiver) {
            return {
                execute: function () {
                    receiver.refresh();
                }
            }
        };
        var refreshMenuBarCommand = RefreshMenuBarCommand("MenuBar");
        setCommand(button1,refreshMenuBarCommand);
    View Code

    ·························有待补充

  • 相关阅读:
    《Python核心编程》数字类型
    我的Android进阶之旅------>Android关于Log的一个简单封装
    Flex中TabNavigator隐藏和显示选项卡
    【HDOJ 5654】 xiaoxin and his watermelon candy(离线+树状数组)
    兔子-svnserver,client搭建
    数据库事务的隔离级别简单总结
    Oracle oledb 打包并集成到程序安装包(VC ADO訪问Oracle)
    kafka分区及副本在broker的分配
    每天进步一点点——mysql——Percona XtraBackup(innobackupex)
    CodeForces 550D Regular Bridge(构造)
  • 原文地址:https://www.cnblogs.com/zhangtianqi520/p/10418317.html
Copyright © 2020-2023  润新知