Class装饰器(实例级)

Class Decorator (instance level)

我正在尝试在 属性 上添加 class decorator 并在 instance.

中修改此 属性

这与 typescript 配合使用效果很好,但我不想使用 typescript,仅 babel 而不是任何其他编译器。

我的猜测是 el 函数中的 targetclass 而不是 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();

我最近遇到了 。因此,我可以告诉你,在使用 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 };
    }
}

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

getter方法中额外的setter调用是在class级别初始化装饰属性时设置请求的return值(在构造函数或成员方法之外)。

If you want it to be compatible with TS, you have to check if the PropertyDescriptor is set and not use the initializer constructor function to fetch the initial value. Replace the calls with target[key] instead.

我不确定 return 仅具有 属性 访问器的新对象或 return 来自装饰器方法的初始 PropertyDescriptor 是否是最佳实践。它只是省略了每次调用修饰的 属性.

时必须删除现有属性,例如 valuewritable