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的典型应用场景。
【参考资料】