Decorators for functions
Ron Buckton
Ron.Buckton at microsoft.com
Thu Oct 22 20:41:33 UTC 2015
> -----Original Message-----
> From: Andrea Giammarchi [mailto:andrea.giammarchi at gmail.com]
> Sent: Thursday, October 22, 2015 12:53 PM
> Ron, there's **no way** you can distinguish a class from a generic function
> in current specifications.
Yes, this is true. However, decorators aren't in the current specification either. If this becomes a must-have then we should investigate an API or meta-property that could expose this information, as I mentioned in my previous reply.
> Having one argument won't tell me much, having a way to know that is not a
> class I need to decorate (traits/mixins) but just a function, so ignoring its
> prototype and do something else, would be cool but it's unfortunately not
> possible or portable.
>
> How would you distinguish between a class or a function for a generic
> decorator? Or all you are saying is that decorators shouldn't be able to
> distinguish at all between a class, rather than a function?
While I think it would be a valuable feature to be able to distinguish between a class and a function, it may make it difficult to properly reason between an ES6 class and an ES5/3 function-as-a-class-constructor. The possibility of adding a "call constructor" further complicates this.
It's useful to be able to disambiguate within the decorator, so I can know whether I would need to maintain a prototype chain:
```js
function someDecorator(target) {
// using "function.decoration" as a possible meta-property
if (function.decoration === "class") {
return class extends target {
constructor(...args) {
// do something in constructor...
super(...args);
}
};
}
else if (function.decoration === "function") {
return function(...args) {
// do something in function...
return target(...args);
};
}
}
```
Alternatively, it would be interesting if all class declarations were implicitly given a Symbol.class property on the constructor declaration. This way older function-as-a-class-constructor implementations could opt-in to stating "I'm a class":
```js
function someDecorator(target) {
if (arguments.length !== 1) throw new TypeError(); // only for class/function
if (target.hasOwnProperty(Symbol.class)) {
// class
}
else {
// function
}
}
// up-level
@someDecorator
class ES6Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
// down-level
function Point(x, y) {
this.x = x;
this.y = y;
}
Point[Symbol.class] = true;
Point = someDecorator(Point) || Point;
```
Ron
More information about the es-discuss
mailing list