类装饰器(实例级)

时间:2017-12-23 17:54:45

标签: javascript typescript es6-class ecmascript-next

我尝试在属性上添加类decorator并在instance中修改此属性。

这适用于typescript,但我不想使用typescript,只使用babel,但不能使用任何其他编译器。

我的猜测是target函数中的elclass而不是instance,而使用typescript时并非如此

如果有人知道如何仅使用babel而不使用typescript

来完成这项工作

使用打字稿进行演示:https://jsfiddle.net/w7xnwbdz/

仅使用babel进行演示:https://jsfiddle.net/w7xnwbdz/1/

function el(type) {
  return function descriptor(target, key,dec) {

    let value = target[key];
     const getter = function() {

      return value;
    };

    const setter = function(newVal) { 
      value = document.createElement(type);
      value.innerHTML = newVal
    };

    if (delete target[key]) {
      Object.defineProperty(target, key, {
        get: getter,
        set: setter,
        enumerable: true,
        configurable: true
      });
    }
  }
}


class App { 

  @el("div")
  logo = "message"

  constructor() {
    console.log(this.logo)
  }
}

let app = new App();

1 个答案:

答案 0 :(得分:1)

我最近遇到similar problem。因此,我可以告诉您,在使用Babel时,您必须使用装饰器的PropertyDescriptor参数来获取初始值并设置属性accessors

function el(type) {
    return function descriptor(target, key, dec) {
        const { initializer } = dec;

        let value = target[key] || null;

        const getter = function () {
            console.log('_getter_')

            if (!value && (value = initializer.call(this))) {
                setter(value);
            }
            return value;
        };

        const setter = function (newVal) {
            console.log('_setter_');

            value = document.createElement(type);
            value.innerHTML = newVal
        };

        return { get: getter, set: setter };
    }
}

根据要求,我更新了您的装饰器,使其适用于只是 Babel。

getter方法中的附加setter调用是在类级别(构造函数或成员方法之外)初始化trim属性时设置请求的返回值。

  

如果希望它与TS兼容,则必须检查PropertyDescriptor是否已设置且使用初始化构造函数来获取初始值。将来电替换为target[key]

我不确定是否最好只使用属性访问器返回一个新对象,或者从装饰器方法返回初始PropertyDescriptor。它只是省略了每次调用装饰属性时都必须删除valuewritable等现有属性。