前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >早读《Understanding JavaScript Decorators》

早读《Understanding JavaScript Decorators》

作者头像
icepy
发布2019-12-24 14:18:17
3600
发布2019-12-24 14:18:17
举报
文章被收录于专栏:子曰五溪

https://www.simplethread.com/understanding-js-decorators/

这是一篇讲 JavaScript 装饰器的文章,目前处于tc39第二阶段,由于是提取精髓,因此略有删减。

装饰器的收益在于可以抽象一部分通用的代码,在共享逻辑上,非常有用,让我们来看一个对属性设置只读的例子:

代码语言:javascript
复制
function readOnly(target, key, descriptor) {
  return {
    ...descriptor,
    writable: false,
  };
}

class Oatmeal extends Porridge {
  @readOnly viscosity = 20;
  // (you can also put @readOnly on the line above the property)

  constructor(flavor) {
    super();
    this.flavor = flavor;
  }
}

我们可以理解装饰器函数传递了三个参数给你使用,分别是 target ,key,descriptor,并且最后需要返回元素或类的属性描述符。

这个属性描述符相信你使用 defineProperty 时肯定用过,是的,就是定一个对象的行为描述。当你在装饰属性或方法时,你可以想象一下,你在操作具体的对象,最后返回一个描述符集合,系统帮助我们完成最后的设定。

代码语言:javascript
复制
function apiRequest(target, key, descriptor) {
  const apiAction = async function(...args) {
    // More about this line shortly:
    const original = descriptor.value || descriptor.initializer.call(this);

    this.setNetworkStatus('loading');

    try {
      const result = await original(...args);
      return result;
    } catch (e) {
      this.setApiError(e);
    } finally {
      this.setNetworkStatus('idle');
    }
  };

  return {
    ...descriptor,
    value: apiAction,
    initializer: undefined,
  };
}

class WidgetStore {
  @apiRequest
  async getWidget(id) {
    const { widget } = await api.getWidget(id);
    this.addWidget(widget);
    return widget;
  }
}

这个 original 就是外部 getWidget 方法。

最后我们再来看一看装饰类,实际上我们只需要传递第一个参数:

代码语言:javascript
复制
function customElement(name) {
  return function(target) {
    customElements.define(name, target);
  };
}

@customElement('intro-message');
class IntroMessage extends HTMLElement {
  constructor() {
    super();
  }
}

最后结论:

https://github.com/tc39/proposal-decorators

目前从公开的文档上来看,设计小组正准备将它重新设计为静态装饰器,未来有没有变动,暂时未知。目前 TypeScript 和 Babel 都对装饰器有支持,TS需要手动开启这个功能。

业务上装饰器用的恰到好处,确实能共享很多代码,但早期采用有一定的成本。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 子曰五溪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档