Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the `target` in javascript decorators

I'm playing with javascript decorators but I'm having a hard time with the target which is passed to the decorator function

For example, if you have

@Bar()
class Foo {
    @deprecated(true)
    doMagic() {}
}

function Bar() {
    return function decorator(target) {

    }
}

function deprecated(state) {
    return function decorator(target, name, config) {
         return config;
    }
}

I would expect that both targets are one and the same thing, right, well it isn't. For example

function Bar() {
    return function decorator(target) {
        let bar = new target(); // WORKS
        bar instanceof target; // -> true
    }
}

function deprecated(state) {
    return function decorator(target, name, config) {
         let bar = new target(); // ERROR
         let bar = new target.constructor() // WORKS

         bar instanceof target; // ‌TypeError: Right-hand side of 'instanceof' is not callable
         bar instanceof target.constructor // WORKS
         return config;
    }
}

As you can see there is a difference between both targets, and my question is what is wrong with that second target

I use node v7.8.0 and I'm using the follow babel plugins (.babelrc)

{
    "presets": [
        "es2015",
       "stage-0"
   ]

}

like image 667
Jeanluca Scaljeri Avatar asked Oct 29 '22 07:10

Jeanluca Scaljeri


People also ask

What is target in decorator TypeScript?

target: Constructor function of the class if we used decorator on the static member, or prototype of the class if we used decorator on instance member. In our case it is firstMessage which is an instance member, so the target will refer to the prototype of the Greeter class. propertyKey: It is the name of the property.

How do JavaScript decorators work?

Decorators are the way of wrapping one piece of code with another or apply a wrapper around a function in JavaScript. Decorators are the design pattern that allows behavior to be added to an individual object, either statically or dynamically without affecting the behavior of other objects from the same class.

What is Decorator pattern in JavaScript?

Decorators are a structural design pattern that aim to promote code reuse. Similar to Mixins, they can be considered another viable alternative to object subclassing. Classically, Decorators offered the ability to add behavior to existing classes in a system dynamically.

What is the purpose of decorators in TypeScript?

Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members. Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript. NOTE Decorators are an experimental feature that may change in future releases.


1 Answers

It sounds like you're using the old legacy decorators. Beware that the decorators proposal has moved on since then and the API is still evolving. The proposal is (as I write this) at Stage 2, e.g. "draft" (see this document for details).

The target in your @deprecated decorator using the old legacy plugin is the object that will ultimately be saved as Foo.prototype. Whereas in @Bar, it's the Foo class constructor itself. That's why in your @deprecated decorator, you can't use new target (target is a non-callable object), but you can use new target.constructor (which is Object).

But again: This stuff is still in flux.

like image 51
T.J. Crowder Avatar answered Nov 10 '22 17:11

T.J. Crowder