修饰器是一个 JavaScript 函数(建议是纯函数),它用于修改类属性/方法或类自己。修饰器提案正处于第二阶段,咱们能够使用 babel-plugin-transform-decorators-legacy 这个 Babel 插件来转换它。ios
@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。
若是要经过修饰器传递参数可在修饰器外面封装一层(多层)函数。git
function Decs(type){ return target => { target.type = 'Topic' + type; target.prototype.type = 'topic ' + type; } }
注意: 修饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。这意味着,修饰器能在编译阶段运行代码。也就是说,修饰器本质就是编译时执行的函数github
看一个例子,经过类修饰器给 React 组件添加 axios 实例: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参数指的是类自己);第二个参数是所要修饰的属性名,第三个参数是该属性的描述对象。segmentfault
基于decorator(修饰器)的方便,封装了一个 axios 的网络请求库,欢迎你们来star retrofit-cjsbabel
来源:https://segmentfault.com/a/1190000016036391网络