J'essaie de comprendre comment utiliser les décorateurs dans un morceau de code très simple, donc je peux appliquer ce concept à mon plus gros projet. S'inspirant de l'article d'Addy Osmani ici , j'ai créé un simple morceau de code comme ci-dessous.
Disons que j'ai une classe appelée Cat
, avec une méthode meow()
, je veux la décorer avec un peu de journalisation, comme ci-dessous.
class Cat {
@logger
meow() { console.log( ' Meeeoow! ') }
};
function logger(target, key, descriptor) {
console.log("Cat snarling...");
return descriptor;
}
const cat = new Cat();
cat.meow();
Lorsque j'essaie d'exécuter cela contre l'interpréteur Node.js (version 9.1.0), j'obtiens l'erreur suivante.
/Users/ravindranath/projects/decorators/index.js: 2 @logger ^ SyntaxError: jeton Non valide ou inattendu sur createScript (vm.js: 80:10) Sur Object.runInThisContext (vm.js: 152: 10) Sur Module._compile (module.js: 605: 28) Sur Object.Module. _extensions..js (module.js: 652: 10) sur Module.load (module.js: 560: 32) sur tryModuleLoad (module.js: 503: 12) sur Function.Module._load (module.js: 495: 3) sur Function.Module.runMain (module.js: 682: 10) au démarrage (bootstrap_node.js: 191 : 16) Sur bootstrap_node.js: 613: 3
Donc, mes questions sont:
Node.js 9.x prend-il en charge la syntaxe du décorateur? Ou est-ce à venir dans une future version?
J'en vois express-js
décorateurs basés sur GitHub, mais je n'arrive pas à comprendre comment créer mon propre décorateur. Quelqu'un peut-il fournir un exemple de base simple de création d'un décorateur personnalisé avec Node.js?
Les décorateurs ne font pas partie d'ECMAScript 2016 (aka 7). Les décorateurs sont actuellement en Projet de l'étape 2 sur les 4 étapes au total, une fonctionnalité passe par avant d'être finalisée et de faire partie de la langue. Ils seront probablement intégrés dans la langue dans un avenir proche, mais ses fonctionnalités et spécificités sont susceptibles de changer. Pour cette raison, vous devrez utiliser un transpilateur tel que Babel pour transformer les décorateurs en code que le runtime Node peut comprendre (ECMAScript 2016) en installant le transform-decorators
Plugin Babel.
Quant à la création de décorateurs, vous l'avez déjà fait. Chaque décorateur est juste une fonction qui en encapsule une autre, qui est fournie avec des arguments basés sur le cas d'utilisation, dans votre cas target
, key
et descriptor
. Votre fonction logger
:
function logger(target, key, descriptor) {
console.log("Cat snarling...");
return descriptor;
}
Est déjà décorateur. Pour les propriétés et méthodes de classe , target
fait référence à la classe de la propriété, key
est le nom de la propriété, et descriptor
est le descripteur de la propriété. Le décorateur est alors appelé et la propriété de la classe est définie via Object.defineProperty
une fois désucré. Votre exemple peut se résumer à ceci:
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()
});
Pour les classes elles-mêmes, les décorateurs prennent un argument, target
qui décrit la classe décorée. Je vous suggère de lire quelques documentations sur le sujet pour en prendre connaissance.