zoukankan      html  css  js  c++  java
  • JS 设计模式九 -- 装饰器模式

    概念

    装饰者(decorator)模式能够在不改变对象自身的基础上,动态的给某个对象添加额外的职责,不会影响原有接口的功能。

    模拟传统面向对象语言的装饰者模式

    //原始的飞机类
    var Plane = function () {
    };
    
    Plane.prototype.fire = function () {
        console.log('发射普通子弹');
    };
    
    
    //装饰类
    var MissileDecorator = function (plane) {
        this.plane = plane;
    }
    
    MissileDecorator.prototype.fire = function () {
        this.plane.fire();
        console.log('发射导弹!');
    };
    
    var plane = new Plane();
    plane = new MissileDecorator(plane);
    plane.fire();

    JavaScript中的装饰器模式

    var Plane = {
        fire: function () {
            console.log('发射普通的子弹');
        }
    };
    
    var missileDecorator= function () {
        console.log('发射导弹!');
    };
    
    var fire = Plane.fire;
    
    Plane.fire=function () {
        fire();
        missileDecorator();
    };
    
    Plane.fire();

    对 window.onload 进行装饰例子

    window.onload=function () {
        console.log('onload');
    };
    
    var  _onload= window.onload || function () {};
    
    window.onload=function () {
        _onload();
        console.log('自己的处理函数');
    };

    使用AOP(面向切面编程)装饰函数

    主要是以为在JavaScript中会存在随着函数的调用,this的指向发生变化,导致执行结果发生变化。

    封装before函数

    在需要执行的函数之前执行某个新添加的功能函数

    //是新添加的函数在旧函数之前执行
    Function.prototype.before=function (beforefn) {
        var _this= this;                               //保存旧函数的引用
        return function () {                           //返回包含旧函数和新函数的“代理”函数
            beforefn.apply(this,arguments);            //执行新函数,且保证this不被劫持,新函数接受的参数
                                                       // 也会被原封不动的传入旧函数,新函数在旧函数之前执行
            return _this.apply(this,arguments);
        };
    };

    封装 after 函数

    在需要执行的函数之后执行某个新添加的功能函数

    //新添加的函数在旧函数之后执行
    Function.prototype.after=function (afterfn) {
        var _this=this;
        return function () {
            var ret=_this.apply(this,arguments);
            afterfn.apply(this,arguments);
            return ret;
        };
    };

    表单验证

    Function.prototype.before=function (beforefn) {
        var _this= this;                               //保存旧函数的引用
        return function () {                           //返回包含旧函数和新函数的“代理”函数
            beforefn.apply(this,arguments);            //执行新函数,且保证this不被劫持,新函数接受的参数
            // 也会被原封不动的传入旧函数,新函数在旧函数之前执行
            return _this.apply(this,arguments);
        };
    };
    
    var validata=function () {
        if(username.value===''){
            alert('用户名不能为空!')
            return false;
        }
        if(password.value===''){
            alert('密码不能为空!')
            return false;
        }
    }
    
    var formSubmit=function () {
        var param={
            username=username.value;
            password=password.value;
        }
    
        ajax('post','http://www.xxx.com',param);
    }
    
    formSubmit= formSubmit.before(validata);
    
    
    submitBtn.onclick=function () {
        formSubmit();
    }
  • 相关阅读:
    Educational Codeforces Round 59 (Rated for Div. 2)E. Vasya and Binary String 区间dp
    MySQL语法大全
    D. Buy a Ticket(优先队列+dijkstra)
    Two Sets(并查集分类)
    KMP浅显易懂
    深度理解链式前向星
    快速幂(幂运算取模的logn算法)
    hdu---1950---Bridging signals解题报告(求Lis n*logn贪心+二分搜索)
    dp背包
    线段树模板
  • 原文地址:https://www.cnblogs.com/gaosirs/p/10756503.html
Copyright © 2011-2022 走看看