4

I'm a new developper in Node.js (coming from Python), and I'm quite surprised to see that there are no decorators in Javascript. I would like to use it, however, because it greatly simplifies the code.

After some research, I found an ES6 specification in stage 2 for this (https://github.com/tc39/proposal-decorators), but it is apparently not supported in Node.js. I also found this in TypeScript, but their function is limited (only in classes).

So my question is: Is there a way to have decorators similar to those of Python with Node.js, and if not, what features can be used as a substitute ?

Thank you in advance for your answers !

baptiste0928
  • 125
  • 1
  • 8
  • 3
    Might be better to explain what you want to do that you think is simpler with decorators. Someone might be able to explain how to do it in JavaScript – Sami Kuhmonen Dec 07 '19 at 18:13
  • 1
    I come from java and I was looking decorators for dependency injection. As @sami said, what is your requirement? Also you can check this https://github.com/jrichardsz/dependency-injection-4nodejs – JRichardsz Dec 07 '19 at 18:17
  • @JRichardsz what's the benefit of your "injection" over `module.exports = express => { express.get(/*...*/) /*...*/ }` ? – Jonas Wilms Dec 07 '19 at 18:38
  • I need decorators to check args of an function before its execution. I think their syntax is very great for doing that. @SamiKuhmonen – baptiste0928 Dec 07 '19 at 18:50
  • #JonasWilms benefit is that you don't need to pass express explicitly to another javascript modules, you just need to use it because the **dependency injection core** must instantiate it at the beginning of your app. If you can, check this https://stackoverflow.com/a/3153617/3957754 and this https://raw.githubusercontent.com/jrichardsz/static_resources/master/dependency-injection/dependency-injection.png – JRichardsz Dec 07 '19 at 19:29
  • Just for your information: https://node.green/ ... great side for learning what's available in Node.js ... for decorators, nothing's available yet: https://node.green/#ESNEXT-Stage-2-Class-and-Property-Decorators – Thomas Urban Mar 16 '23 at 20:32

2 Answers2

4

According to Wikipedia decorators in python are just syntactic sugar for a function call, which takes the original class/function and stores the returned value under the variable containing the class. Thus the equivalent js would be:

  const Decorated = decorator(class ToBeDecorated {
     /*...*/
  });

  const decoratedFunction = decorateFunction(function decorated() {
     /*...*/
  });

  // Some sample decorator implementations:
  const decorator = Parent => class WithDuck extends Parent {
   quack() { }
  };

  const decorateFunction = fn => (...args) => {
     console.log(`${fn.name} called with`, ...args);
     return fn(...args);
  };
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

@jonas Wilms 's answer is correct. I wanted to post this here to expand on a specific implementation technique I used. My use case was with Koa, using async/await functions.

First, I created my decorator:

export function Cocoon( { param=[] }, callback )
{
    //Return a function from the decorator
    return async (ctx) => {
        //Do a thing with Param
        const params = { usr: param }

        return await callback( ctx, params )
    }
}

Using the decorator to annotate a function:

export const list = Cocoon({ 
        param: [5]
    },
    async (ctx, { usr }) => {
        //Function body
        ctx.response.body = usr
    }
)

Now I can export 'list' to Koa and it'll be called as expected.

Luke Dupin
  • 2,275
  • 23
  • 30