通过类装饰器自动将类添加到列表中?

时间:2019-01-25 20:15:42

标签: javascript decorator

是否可以在装饰器中获取“类对象”(构造函数)的句柄?

背景:我想用带有类型标记的字符串值来解析json'ish格式。 "@date:2019-01-25""@latlong:51.507351,-0127758"

这是对旧版js库的现代化改进,它是通过覆盖子类和实例创建来实现的。

装饰器看起来很有希望,至少我可以将标签定义为类属性:

function dkdatatype({tag}) {
    return function decorator(cls) {
        if (cls.kind !== 'class') throw `not class ${cls.kind}`;

        cls.elements.push({
            kind: 'field',
            key: 'tag',
            placement: 'static', 
            descriptor: {
                configurable: false,
                enumerable: true,
                writable: false
            },
            initializer: () => tag
        });

        return {
            kind: 'class',
            elements: cls.elements
        };
    };
}

@dkdatatype({tag: '@date:'})
export class DkDate extends datatype {
    constructor(...args) {
        super();
        const clstag = this.constructor.tag;
        if (typeof args[0] === 'string' && args[0].startsWith(clstag)) {
            this.value = new Date(args[0].substr(clstag.length));
        } else {
            this.value = new Date(...args);
        }
    }
    toJSON() {
        return this.constructor.tag + this.value.toISOString().slice(0, 10);
    }
}

我可以手动将类添加到类型注册表:

type_registry[DkDate.tag] = DkDate

但是有没有办法从装饰器(或者也许是基类,或者其他方式)自动(仅一次)执行此操作?

1 个答案:

答案 0 :(得分:1)

根据current proposal docs,您想向装饰器返回的类描述符中添加一个extras属性,该属性应包含一个“钩子”描述符,并且该描述符应具有一个{{1 }}方法,一旦完全定义了类,将使用该类本身作为参数来调用。

这是示例代码:

finish

在您的情况下,function defineElement(tagName) { return function(classDescriptor) { let { kind, elements } = classDescriptor; assert(kind == "class"); return { kind, elements, // This callback is called once the class is otherwise fully defined extras: [ { kind: "hook", placement: "static", finish(klass) { window.customElements.define(tagName, klass); } } ] }; }; 看起来像这样:

extras