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的典型應用場景。
【參考資料】