如何使用和应用 JavaScript 装饰器?
Posted
技术标签:
【中文标题】如何使用和应用 JavaScript 装饰器?【英文标题】:How do I use and apply JavaScript decorators? 【发布时间】:2018-06-11 20:27:20 【问题描述】:我正在尝试了解如何在一段非常简单的代码中使用装饰器,因此我可以将这个概念应用到我更大的项目中。借鉴 Addy Osmani 的文章 here,我创建了一段简单的代码,如下所示。
比如说,我有一个名为Cat
的类,有一个meow()
方法,我想用一些日志来装饰它,如下所示。
class Cat
@logger
meow() console.log( ' Meeeoow! ')
;
function logger(target, key, descriptor)
console.log("Cat snarling...");
return descriptor;
const cat = new Cat();
cat.meow();
当我尝试对 Node.js 解释器(版本 9.1.0)执行此操作时,我收到以下错误。
/Users/ravindranath/projects/decorators/index.js:2 @logger ^ SyntaxError:无效或意外的令牌 在 createScript (vm.js:80:10) 在 Object.runInThisContext (vm.js:152:10) 在 Module._compile (module.js:605:28) 在 Object.Module._extensions..js (module.js:652:10) 在 Module.load (module.js:560:32) 在 tryModuleLoad (module.js:503:12) 在 Function.Module._load (module.js:495:3) 在 Function.Module.runMain (module.js:682:10) 启动时(bootstrap_node.js:191:16) 在 bootstrap_node.js:613:3
所以,我的问题是:
Node.js 9.x 是否支持装饰器语法?还是会在未来的某个版本中出现?
我在 GitHub 上看到了一些基于 express-js
的装饰器,但我无法弄清楚如何创建自己的装饰器。有人可以提供一个使用 Node.js 创建自定义装饰器的简单基本示例吗?
【问题讨论】:
你可以在这里查看node.green 我写了一篇关于如何快速入门的短文 - dev.to/dpkshrma/… 【参考方案1】:装饰器不是 ECMAScript 2016(又名 7)的一部分。装饰器目前处于Stage 2 Draft 中,一个功能在最终确定并成为语言的一部分之前要经历的总共 4 个阶段。它们可能会在不久的将来集成到该语言中,但其功能和细节可能会发生变化。因此,您必须使用 Babel 等转译器通过安装 transform-decorators
Babel 插件将装饰器转换为 Node 运行时可以理解的代码(ECMAScript 2016)。
至于创建装饰器,您已经这样做了。每个装饰器只是一个包装另一个的函数,它提供了基于用例的参数,在您的情况下为target
、key
和descriptor
。你的logger
函数:
function logger(target, key, descriptor)
console.log("Cat snarling...");
return descriptor;
已经是一名装饰师了。对于类属性和方法,target
指的是属性的类,key
是属性名称,descriptor
是属性的描述符。然后调用装饰器并通过Object.defineProperty
定义类的属性,一旦去糖。您的示例可以归结为:
class Cat
let meowDescriptor =
type: 'method',
initializer: () => () =>
console.log(' Meeeoow! ');
,
enumerable: false,
configurable: true,
writable: true
function logger(target, key, descriptor)
console.log("Cat snarling...");
return descriptor;
meowDescriptor = logger(Cat.prototype, 'meow', meowDescriptor);
Object.defineProperty(Cat.prototype, 'meow',
...meowDescriptor,
value: meowDescriptor.initializer()
);
对于类本身,装饰器采用一个参数,target
,它描述了被装饰的类。我建议阅读some documentation 以熟悉该主题。
【讨论】:
三年后,它仍处于第 2 阶段草稿 :( 我正在编写 Node 服务 - 我认为在这里我会很安全,不需要使用转译器。以上是关于如何使用和应用 JavaScript 装饰器?的主要内容,如果未能解决你的问题,请参考以下文章