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();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM