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"
]
}
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With