大数据

javascript 装饰者模式

装饰者模式:给对象动态添加职责的方式就是装饰者模式,能够在不改变原对象的情况下,在运行的时候给对象添加新的职责。
参考《javascript设计模式与开发实践》

下面重点是介绍一个AOP的例子,AOP是面向切面编程,在下面的函数运行的时候,可以给把函数看做有一个生命周期,分为 运行前(before),运行中,运行后(after)。在运行前,运行后可以给函数对象添加不同的职责,这些添加的职责不会影响原函数对象的运行。

在javascript中几乎一切都是对象,函数作为一等对象,可以作为函数的参数传递,所以在js中使用装饰者模式的时候后很大的便利性。

AOP的标准模型
//argument对象是函数调用时,隐式传递的函数参数
Function.prototype.before = function( beforefn ){
        var __self = this; // 保存原函数的引用
        return function(){ // 返回包含了原函数和新函数的"代理"函数
            beforefn.apply( this, arguments ); // 执行新函数,且保证this
// 不被劫持,新函数接受的参数也会被原封不动地传入原函数,新函数在原函数之前执行
            return __self.apply( this, arguments ); // 执行原函数并返
//回原函数的执行结果, 并且保证this 不被劫持        
    }
}

Function.prototype.after = function( afterfn ){
    var __self = this;
    return function(){
        var ret = __self.apply( this, arguments );
        afterfn.apply( this, arguments );
        return ret;
    }
};

实例:点击按钮时弹框之后统计弹框的参数

//log函数作为参数传递  
Function.prototype.after = function( afterfn ){
        var __self = this; //保存原函数的引用,_在js中是可以使用的可以作为一个私有方法和变量的起始标志
        return function(){ //返回函数复合体
            var ret = __self.apply( this, arguments );//原函数调用
            afterfn.apply( this, arguments );//after函数调用
            return ret; //返回原函数
        }
    };
    var showLogin = function(){
        console.log( '打开登录浮层' );
    }
    var log = function(){
        console.log( '上报标签为: ' + this.getAttribute( 'tag' ) );
    }

    showLogin = showLogin.after( log ); // 打开登录浮层之后上报数据
    document.getElementById( 'button' ).onclick = showLogin;

在javascript中。面向对象编程和函数式编程是不矛盾的。两者结合起来威力更大。随着学习的深入,你会觉得满满的都是套路和模式。到了这一步学习有点欲罢不能了。学习javascript真是有意思。