Port features to ES6
I would like to see native support if possible for classes. I need to see what we can get away with first.
Maybe the root constructor upon initialization will process all methods? But this wouldn't work when calling static methods.
However if Proxies were supported we could leverage them, its still looking like we may be forced to use a custom constructor still.
We can do this with instance methods in the base constructor like this
class Base {
constructor() {
var proto = this;
while (proto = proto.__proto__) {
if (proto instanceof Object) {
Object.getOwnPropertyNames(proto).forEach(function (className, instance) {return function (name) {
var func = proto[name].bind(instance);
proto[name] = function () {
console.log(className + ':' + name + ':injection:before');
func();
console.log(className + ':' + name + ':injection:after');
};
}}(proto.constructor.name, this));
}
}
}
}
As for class methods, i have no idea how to achieve this :(. The shitty way would be to do the following
PromiseObject.create(
class Square extends Base {
}
);
var square = new Square();
this is a bit of a hack but i guess it works
function wrapMethods (classConstructor, object, wrapper) {
var className = classConstructor.name;
Object.getOwnPropertyNames(object).forEach(function (propertyName) {
if (typeof object[propertyName] !== 'function') {
return;
}
var func = object[propertyName].bind(object);
object[propertyName] = wrapper(className, propertyName, func);
});
}
function wrapClass (classConstructor) {
wrapMethods(classConstructor, classConstructor, function (className, propertyName, func) {
return function () {
console.log(className + ':' + propertyName + ':class:injection:before');
func();
console.log(className + ':' + propertyName + ':class:injection:after');
}
});
if (classConstructor.name) {
(new Function('constructorObject', classConstructor.name + ' = constructorObject')).call(null, classConstructor);
}
return classConstructor;
}
I have decided to create a new project called PromiseClass. I have a solution to all my concerns and it will result in the following syntax for definition
PromiseClass(class Person {
constructor() {
}
*getUser($deferred, id) {
$deferred.resolve(yield database.query(...));
}
});
I have a working solution but i ended up losing the ability to do the following:
- pseudo params in constructors :(
- reopen + super (but you can still use reopen to create wrapped methods)
Its not a show stopper, i also decided to use co, and auto-enable bluebird if it exists
This means that you can actually use yields without having to use bluebird. This also resulted in a 30X increase in speed when doing yielded promises ;). Bluebird is much faster than the native Promise, and co.wrap is much faster than Bluebird.coroutine .