web-dev-qa-db-fra.com

Comment utiliser et appliquer des décorateurs JavaScript?

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:

  1. Node.js 9.x prend-il en charge la syntaxe du décorateur? Ou est-ce à venir dans une future version?

  2. 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?

10

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.

10
Li357