簡體   English   中英

使用非傳統裝飾器時如何裝飾 JavaScript class 構造函數?

[英]How to decorate a JavaScript class constructor when using non-legacy decorators?

我有以下 class:

@log
class Example {
  constructor(name, age) {
    console.log("Example constructor", name, age);
    this.name = name;
    this.age = age;
  }
}

使用舊版裝飾器時,這個@log裝飾器:

function log(Class) {
  return class extends Class {
    constructor(...args) {
      console.log("log", args);
      super(...args);
    }
  };
}
// .babelrc
// ...
      "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        // ...
      ]
// ...

上面的設置效果很好,下面的代碼:

const example = new Example("Graham", 34);

輸出:

log (2) ["Graham", 34]
Example constructor Graham 34

現在,如何在使用非傳統裝飾器時獲得相同的結果,即:

// .babelrc
// ...
      "plugins": [
        [
          "@babel/plugin-proposal-decorators",
          { "decoratorsBeforeExport": false }
        ],
        // ...
      ]
// ...

我如何實現@log以便它以與傳統裝飾器相同的方式工作?

function log(...args) {
  const [descriptor] = args;
  const { kind, elements } = descriptor;

  const newElements = elements.concat({
    kind: "method",
    placement: "prototype",
    key: "constructor",
    descriptor: {
      value: (...args) => {
        // I have tried this but it doesn't work...
        console.log("log", args);
      },
      configurable: true,
      writable: true,
      enumerable: true,
    },
  });

  return {
    kind,
    elements: newElements,
  };
}

我已經嘗試了上面的代碼,但它沒有工作。 問題是我在使用非傳統裝飾器時沒有對目標的引用。 你知道是否有一種方法可以實現與傳統行為相同的行為?

謝謝你。

感謝BabelJS Slack 頻道上的 loganfsmyth,我找到了答案。

您必須返回一個 object,其中包含一個名為 Finisher 的屬性,該屬性包含finisher ,例如:

function log(...args) {
  const [descriptor] = args;
  const { kind, elements } = descriptor;

  return {
    kind,
    elements,
    finisher: (Class) => {
      return class extends Class {
        constructor(...args) {
          console.log("log", args);
          super(...args);
        }
      };
    }
  };
}

然后在使用非傳統裝飾器時使用此代碼:

@log
class Example {
  constructor(name, age) {
    console.log("Example constructor", name, age);
    this.name = name;
    this.age = age;
  }
}

const example = new Example("Graham", 34);

輸出:

log (2) ["Graham", 34]
Example constructor Graham 34

與傳統裝飾器一樣。

很難找到答案,因為@babel/plugin-proposal-decorators上沒有記錄非傳統裝飾器的這個特性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM