修饰器
修饰器是一个 JavaScript 函数(建议是纯函数),它用于修改类属性/方法或类本身。修饰器提案正处于第二阶段,我们可以使用 babel-plugin-transform-decorators-legacy 这个 Babel 插件来转换它。
类修饰器
@Dec
class Topic{
}
function Dec(target){
target.type = 'Topic'; // 类的静态属性
target.prototype.type = 'topic object'; //类的实例属性
}
var topic = new Topic();
console.log(Topic.type); // Topic
console.log(topic.type); // topic object
修饰器是一个对类进行处理的函数。类修饰器函数的第一个参数,就是所要修饰的目标类。
函数Dec的参数target,就是被修饰的类。如果要在类的实例上添加属性可通过 target.prototype。
如果要通过修饰器传递参数可在修饰器外面封装一层(多层)函数。
function Decs(type){
return target => {
target.type = 'Topic' + type;
target.prototype.type = 'topic ' + type;
}
}
注意: 修饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。这意味着,修饰器能在编译阶段运行代码。也就是说,修饰器本质就是编译时执行的函数
看一个例子,通过类修饰器给 React 组件添加 axios 实例:
//App.js
@Create({
baseURL: 'https:xxx.xxx.xxx',
})
class App extends Component{
constructor(props) {
super(props);
}
componentWillMount() {
this.$axios.get('/user?ID=12345');
}
}
// Create修饰器
const Create = config => (target, property, descriptor) => {
// 避免在类的方法上使用
if (!descriptor) {
target.prototype.$axios = axios.create(config);
}
}
类方法修饰器
class App extends Component{
constructor(props) {
super(props);
}
@GET('/user?ID=12345')
getUser(res) {
//
}
}
// axios get请求简单封装
function GET(url){
return function(target, name, descriptor) {
let oldVal = descriptor.value;
// descriptor.value为当前修饰器所修饰的属性值
descriptor.value = function(){
axios.get(url)
.then((res)=>{
oldVal.apply(this, res.data);
}).catch((err)=>{
oldVal.apply(this, {}, err)
});
}
}
}
类方法的修饰器函数一共可以接受三个参数,第一个参数是类的原型对象,上例是App.prototype,修饰器的本意是要“修饰”类的实例,但是这个时候实例还没生成,所以只能去修饰原型(这不同于类的修饰,那种情况时target参数指的是类本身);第二个参数是所要修饰的属性名,第三个参数是该属性的描述对象。
最后
基于decorator(修饰器)的方便,封装了一个 axios 的网络请求库,欢迎大家来star retrofit-cjs