簡體   English   中英

帶有第 2 階段提案和 Babel 7 的類裝飾器

[英]Class decorator with stage-2 proposal and Babel 7

我正在玩第 2 階段裝飾器提案,我發現類裝飾器存在一些問題。 在遺留裝飾器中,下一個示例有效,因為類裝飾器將目標構造函數作為其唯一參數,但在第 2 階段提議中接收對象描述符。

function log(Class) {
  return (...args) => {
    console.log(`Arguments: ${args}`);

    return new Class(...args);
  };
}

@log
class Bar {
  constructor(name, age) { }
}

我已經閱讀了 tc39 提案裝飾器和內置裝飾器,但它對我沒有多大幫助。 我怎樣才能讓這個例子與新的提案裝飾器一起工作? 是否可以在 babel 中使用內置裝飾器?

為了嘗試一些東西,我開發了自己的基本包裝裝飾器,它按預期方法工作,並且我想將其功能擴展到類。

const wrap = f => {
 return wrapped => {
   const { kind } = wrapped;

   if (kind === 'class') {
     return f(wrapped);
   }
   const { descriptor } = wrapped;
   const original = descriptor.value;

   descriptor.value = f(original);

   return { ...wrapped, descriptor };
  };
};

export default wrap;

使用這個基本的裝飾器,我可以創建例如這個有效的記錄器方法裝飾器。

import wrap from './wrap';

const loggerFunction = f => {
  const name = f.name;

  return function test(...args) {
    console.log(`starting ${name} with arguments ${args.join(', ')}`);

    return f.call(this, ...args);
  };
};

export default wrap(loggerFunction);

我可以通過這種方式使用它:

class Foo {
  @logger
  method(argument) {
    return argument;
  }
}

你的問題有點老了,但我認為它仍然是實際的,所以這是我的答案:

TLDR:使用一個finisher財產使用非傳統的階段2個裝飾時,包裹類。

第 2 階段的 API 沒有完全記錄,並且缺少一些東西和用例。

為了實現您想要的效果,請在裝飾器中返回的對象上定義一個特殊的finisher屬性。

因此,這個legacy stage-1 裝飾器代碼:

function log(Class) {
  return (...args) => {
    console.log(`Arguments: ${args}`);

    return new Class(...args);
  };
}

@log
class Bar {
  constructor(name, age) { }
}

將等效於這個non-legacy第 2 階段裝飾器代碼:

function log(descriptor) {
  return {
    ...descriptor,
    finisher: (Class) => (...args) => {
      console.log(`Arguments: ${args}`);

      return new Class(...args);
    },
  };
}

@log
class Bar {
  constructor(name, age) {}
}

您可以將相同的原則應用於wrap功能。

暫無
暫無

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

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