decorator 類的裝飾器
許多面向對象的語言都有修飾器(Decorator)函數,用來修改類的行爲。
目前瀏覽器或者最近的node 8.x + 均不支持裝飾器;可採用babel轉譯:
相關文檔:
- https://babeljs.io/docs/en/babel-plugin-proposal-decorators //裝飾器
- https://babeljs.io/docs/en/babel-plugin-proposal-class-properties //類的屬性
下面已babel7配置爲例:
@babel/plugin-proposal-decorators
@babel/plugin-proposal-class-properties
.babelrc
{
"presets": ["@babel/preset-env"],
"plugins": [
["@babel/plugin-transform-runtime",{"corejs": 2}],
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose" : true }]
]
}
裝飾器分爲:
類的裝飾器
/**
* @class 類的修飾器
*/
@controller('/admin')
class Point {
constructor(obj){
}
}
function controller(router){
return function (target){
//在Point 的原型對象上添加共享屬性decorator
target.prototype.name = `我是裝飾器${router}`
}
}
console.log(new Point().name) //我是裝飾器/admin
/**
* 原生方法
*/
function Point(){
let controller= (router) =>{
return `我是裝飾器${router}`
}
this.name = controller('/admin')
}
console.log(new Point().name) //我是裝飾器/admin
類屬性的裝飾器
class Point {
constructor(obj){
var {x,y} = obj
this.x = x;
this.y = y;
}
@readonly
name(a,b){
return (`${this.x} ${this.y}`)
}
}
/**
*
* @param {*} target 原始對象
* @param {*} name 屬性
* @param {*} descriptor 值
* 類似:Object.defineProperty(Person.prototype, 'name', descriptor);
*/
function readonly(target, name, descriptor){
var oldValue = descriptor.value;
descriptor.value = function() {
let [a,b] = arguments;
console.log(a) //3
console.log(`Calling ${name} with`, arguments);
console.log(this.x) //小明
return oldValue.apply(this, arguments);
};
return descriptor;
}
var b = new Point({x:'小明',y:123})
console.log(b.name(3,888))
下面是使用案例:
/**
* @class 類的修飾器
*/
@testable
class Point {
constructor(obj){
var {x,y} = obj
this.x = x;
this.y = y;
}
@readonly
name(a,b){
return (`${this.x} ${this.y}`)
}
}
/**
*
* @param {*} target 原始對象
* @param {*} name 屬性
* @param {*} descriptor 值
* 類似:Object.defineProperty(Person.prototype, 'name', descriptor);
*/
function readonly(target, name, descriptor){
var oldValue = descriptor.value;
descriptor.value = function() {
let [a,b] = arguments;
console.log(a) //3
// console.log(`Calling ${name} with`, arguments);
// console.log(this.x)
return oldValue.apply(this, arguments);
};
return descriptor;
}
/**
*
* @param {*} target 類的修飾器
* 類似:Object.prototype | Object.xxx
* 可以給原型鏈添加屬性和方法讓實例共享其屬性 | 可以給類添加靜態屬性方法
*/
function testable(target) {
target.prototype.isTestable = true;
}
var b = new Point({x:'小明',y:123})
console.log(b.name(3,888))