简体   繁体   English

带有第 2 阶段提案和 Babel 7 的类装饰器

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

I am playing with stage-2 decorators proposal and I have found some problems with class decorators.我正在玩第 2 阶段装饰器提案,我发现类装饰器存在一些问题。 In legacy decorator, the next example works because class decorators took as their only argument a target constructor, but with stage-2 proposal receives a object descriptor.在遗留装饰器中,下一个示例有效,因为类装饰器将目标构造函数作为其唯一参数,但在第 2 阶段提议中接收对象描述符。

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

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

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

I have read the tc39 proposal-decorators and built-in decorators,but it did not help me so much.我已经阅读了 tc39 提案装饰器和内置装饰器,但它对我没有多大帮助。 How can I make this example works with the new proposal decorator?我怎样才能让这个例子与新的提案装饰器一起工作? is it possible to use built-in decorators with babel?是否可以在 babel 中使用内置装饰器?

To try some stuff, I developed my own basic wrap decorator, it works as expected for methods, and I want to extend its functionality to class.为了尝试一些东西,我开发了自己的基本包装装饰器,它按预期方法工作,并且我想将其功能扩展到类。

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;

With this basic decorator, I can create for example this logger method decorator that works.使用这个基本的装饰器,我可以创建例如这个有效的记录器方法装饰器。

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);

And I can use it by this way:我可以通过这种方式使用它:

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

Your question is a bit old, but I think it is still actual so here is my answer:你的问题有点老了,但我认为它仍然是实际的,所以这是我的答案:

TLDR: Use a finisher property to wrap your class when using non-legacy stage 2 decorators. TLDR:使用一个finisher财产使用非传统的阶段2个装饰时,包裹类。

The stage 2 API is not thoroughly documented and some things and use cases are missing.第 2 阶段的 API 没有完全记录,并且缺少一些东西和用例。

In order to achieve what you want, define a special finisher property on the object you are returning in your decorator.为了实现您想要的效果,请在装饰器中返回的对象上定义一个特殊的finisher属性。

Therefore, this legacy stage-1 decorator code:因此,这个legacy stage-1 装饰器代码:

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

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

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

Will be equivalent to this non-legacy stage-2 decorator code:将等效于这个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) {}
}

You can apply the same principle to your wrap function.您可以将相同的原则应用于wrap功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Babel-cli类属性不适用于Stage-2 - Babel-cli class properties are not working with stage-2 Rails Webpacker和stage-2类转换属性不起作用 - Rails Webpacker and stage-2 class transform properties not working @ babel / plugin-proposal-class-properties不起作用 - @babel/plugin-proposal-class-properties doesn't work 带有 Babel 的 ESLint:在 .eslintrc 中未找到声明的 plugin-proposal-class-properties - ESLint with Babel: plugin-proposal-class-properties not found declared in .eslintrc 错误:找不到模块“@babel/plugin-proposal-class-properties” - Error: Cannot find module '@babel/plugin-proposal-class-properties' 当前未启用对实验语法“classProperties”的支持 (8:16)。 添加@babel/plugin-proposal-class-properties - Support for the experimental syntax 'classProperties' isn't currently enabled (8:16). Add @babel/plugin-proposal-class-properties @babel/plugin-proposal-class-properties 仍然失败,“classProperties 当前未启用” - @babel/plugin-proposal-class-properties Still Fails with "classProperties isn't currently enabled" Babel-装饰类属性的装饰器在实例化类之前被调用 - Babel - decorator of decorated class properties is called before instantiating class Transpile Async等待Babel.js的提案? - Transpile Async Await proposal with Babel.js? Babel插件 - 提议装饰器未按预期工作 - Babel plugin-proposal-decorators not working as expected
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM