Javascript 班级装饰师,第二阶段提案和巴别塔7

Javascript 班级装饰师,第二阶段提案和巴别塔7,javascript,class,decorator,babeljs,ecmascript-next,Javascript,Class,Decorator,Babeljs,Ecmascript Next,我在玩stage-2 decorators提案,我发现类decorators存在一些问题。在legacy decorator中,下一个示例是有效的,因为类decorator将目标构造函数作为其唯一参数,但使用stage-2建议将接收对象描述符 function log(Class) { return (...args) => { console.log(`Arguments: ${args}`); return new Class(...args); }; }

我在玩stage-2 decorators提案,我发现类decorators存在一些问题。在legacy decorator中,下一个示例是有效的,因为类decorator将目标构造函数作为其唯一参数,但使用stage-2建议将接收对象描述符

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

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

@log
class Bar {
  constructor(name, age) { }
}
我读过tc39建议的decorators和内置decorators,但对我没有太大帮助。如何使此示例与新的提案装饰器一起工作?有可能将内置装饰器与巴贝尔一起使用吗

为了尝试一些东西,我开发了自己的基本wrap decorator,它可以像预期的那样用于方法,我想将其功能扩展到类

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;
有了这个基本的decorator,我可以创建这个logger方法decorator

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:使用非旧式阶段2装饰器时,请使用
finisher
属性包装类

第2阶段API没有完整的文档记录,并且缺少一些东西和用例

为了达到您想要的效果,请在装饰器中返回的对象上定义一个特殊的
finisher
属性

因此,此
遗留
阶段1装饰器代码:

函数日志(类){
返回(…参数)=>{
log(`Arguments:${args}`);
返回新类(…参数);
};
}
@日志
分类栏{
构造函数(名称、年龄){}
}
将等同于此
非旧式
阶段2装饰器代码:

函数日志(描述符){
返回{
…描述符,
完成者:(类)=>(…参数)=>{
log(`Arguments:${args}`);
返回新类(…参数);
},
};
}
@日志
分类栏{
构造函数(名称、年龄){}
}

您可以将相同的原则应用于您的
wrap
函数。

“我开发了自己的基本wrap decorator”-您可以展示一下如何使用它,以及它在哪里工作(或不工作)?@Bergi当然!我用那个例子编辑了我的问题。