How do I use and apply JavaScript decorators?

17,814

Decorators are not part of ECMAScript 2016 (aka 7). Decorators are currently in Stage 2 Draft out of the total 4 stages a feature goes through before being finalized and becoming part of the language. They'll probably be integrated into the language in the near future, but its features and specifics are subject to change. Because of this, you'll have to use a transpiler such as Babel to transform the decorators into code the Node runtime can understand (ECMAScript 2016) by installing the transform-decorators Babel plugin.

As for creating decorators, you've already done so. Each decorator is just a function that wraps another, that is provided with arguments based on the usecase, in your case target, key, and descriptor. Your logger function:

function logger(target, key, descriptor) {
  console.log("Cat snarling...");
  return descriptor;
}

Is already a decorator. For class properties and methods, target refers to the class of the property, key is the property name, and descriptor is the descriptor of the property. The decorator is then called and the property of the class is defined via Object.defineProperty once desugared. Your example can be boiled down to this:

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

For classes themselves, decorators take one argument, target which describes the decorated class. I suggest reading some documentation on the subject to become acquainted with it.

Share:
17,814
Mopparthy Ravindranath
Author by

Mopparthy Ravindranath

A software geek, but not an expert. Loves object oriented programming through C++, but trying to be conversant with Java as well. Now a NodeJS geek, ReactJS admirer, D3JS fan and javascript amateur.

Updated on June 03, 2022

Comments

  • Mopparthy Ravindranath
    Mopparthy Ravindranath about 2 years

    I am trying to understand how to use decorators in a very simple piece of code, so I can apply this concept to my bigger project. Taking cue from Addy Osmani's article here, I created a simple piece of code as below.

    Say, I have a class called Cat, with a meow() method, I want to decorate it with some logging, as below.

    class Cat {
      @logger
      meow() { console.log( ' Meeeoow! ') }
    };
    
    
    function logger(target, key, descriptor) {
      console.log("Cat snarling...");
      return descriptor;
    }
    
    const cat = new Cat();
    cat.meow();
    

    When I try to execute this against the Node.js interpreter (version 9.1.0), I get the following error.

    /Users/ravindranath/projects/decorators/index.js:2   @logger   ^
    
    SyntaxError: Invalid or unexpected token
        at createScript (vm.js:80:10)
        at Object.runInThisContext (vm.js:152:10)
        at Module._compile (module.js:605:28)
        at Object.Module._extensions..js (module.js:652:10)
        at Module.load (module.js:560:32)
        at tryModuleLoad (module.js:503:12)
        at Function.Module._load (module.js:495:3)
        at Function.Module.runMain (module.js:682:10)
        at startup (bootstrap_node.js:191:16)
        at bootstrap_node.js:613:3
    

    So, my questions are:

    1. Does Node.js 9.x support decorator syntax? Or is it coming up in some future version?

    2. I see some express-js based decorators on GitHub, but I am unable to figure out how to create my own decorator. Can someone provide a simple basic example of creating a custom decorator with Node.js?

  • Snake Verde
    Snake Verde about 3 years
    Three years later, and it's still in stage 2 draft :( I'm writing Node services - I thought here I'd be safe and not need to use a transpiler.