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))