ES7(ES2016)中的Decorator

Decorator,字面意思是修饰器。用来修饰啥呢? 。先看一段代码index.js

let readOnly = function(target, name, descriptor){
    descriptor.writable=false;
    return descriptor
}

class ClassA {
    @readOnly
    boo() {
        console.log('can not writable');
    }
}

let a = new ClassA();
console.log(a.boo());
a.boo = function(){
    console.log('new foo');
}; // 
console.log(a.boo());

PS:上面代码的运行需要babel。

安装babel

npm install babel-cli -g 
npm install babel-plugin-transform-decorators-legacy --save-dev

在程序根目录下创建文件.babelrc,内容如下

{
  "plugins": ["transform-decorators-legacy"]
}

然后将babel代码转换成普通的ES5代码:

babel --optional es7.decorators index.js > index.es5.js

执行index.es5.js

// can not writable

并没有看到修改后的foo输出new foo

装饰者模式

在不改变原有对象基础上,丰富原对象的功能。

function A(){
    this.name = 'A';
}
A.prototype.say=function(){console.log(this.name)}

var say1 = A.prototype.say;

A.prototype.say=function(){
    say1.call(this);
    console.log("I am new say fn ");
}
var a = new A();
a.say();

装饰者模式的一个应用场景有哪些?
面向切面编程 Aspect Oriented Programming(AOP)

下面的例子中一个前置装饰,一个后置装饰。

Function.prototype.before=function(beforeFn){
    var that = this;
    return function(){
        beforeFn.apply(this, arguments);
        return that.apply(this, arguments);
    }
}
Function.prototype.after=function(afterFn){
    var that = this;
    return function(){
        var result = that.apply(this, arguments);
        afterFn.apply(this, arguments);
        return result;
    }
}
function foobar(x, y){
    console.log(x, y)
}

function foo(x, y){
    console.log(x/10, y/10);
}

function bar(x, y){
    console.log(x*10, y*10);
}

foobar = foobar.before(foo).after(bar);

foobar(2,3);
// 0.2 0.3
// 2 3
// 20 30

Decorator与日志系统

const http = require('http');

function log(target, name, descriptor) {
    var oldValue = descriptor.value;

    descriptor.value = function (req, res) {
        console.log(`${req.method} ${req.url}`)
        return oldValue.apply(null, arguments);
    };

    return descriptor;
}

class Router {
    @log
    router(req, res){
        res.end('okay');
    }
}
const server = http.createServer((req, res) => {
    (new Router()).router(req, res);
});

server.listen(3000, ()=>{
    console.log('server has started......')
});

这个日志系统简单的记录访问路径(Method + URL);

AOP的应用场景相对而言,还是比较广泛的。日志系统、安全控制/访问控制、性能监测以及缓存等,这些都是AOP的典型应用场景。

【参考资料】

ES7 Decorator 装饰者模式

猜你喜欢

转载自blog.csdn.net/u013137242/article/details/83180684
ES7