从javascript属性装饰器(babel传统装饰器)访问对象

时间:2017-03-14 06:54:51

标签: javascript decorator babeljs

是否可以通过属性装饰器访问创建的对象?

function decorator(target, name, descriptor) {
  // somehow get object when it will be created

  return {
    configurable: true,
    enumerable: true,
    get: function () {
      // ...
    },
    set: function (value) {
      // ...
    },
  }
}

class MyClass {
  @decorator
  property = 0;
}

我找到了一个解决方案,但它不适合我的用例。 Babel将上层代码转换为:

var _desc, _value, _class, _descriptor;

function _initDefineProp(target, property, descriptor, context) {
  if (!descriptor) return;
  Object.defineProperty(target, property, {
    enumerable: descriptor.enumerable,
    configurable: descriptor.configurable,
    writable: descriptor.writable,
    value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
  });
}

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
  var desc = {};
  Object['ke' + 'ys'](descriptor).forEach(function (key) {
    desc[key] = descriptor[key];
  });
  desc.enumerable = !!desc.enumerable;
  desc.configurable = !!desc.configurable;

  if ('value' in desc || desc.initializer) {
    desc.writable = true;
  }

  desc = decorators.slice().reverse().reduce(function (desc, decorator) {
    return decorator(target, property, desc) || desc;
  }, desc);

  if (context && desc.initializer !== void 0) {
    desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
    desc.initializer = undefined;
  }

  if (desc.initializer === void 0) {
    Object['define' + 'Property'](target, property, desc);
    desc = null;
  }

  return desc;
}

function _initializerWarningHelper(descriptor, context) {
  throw new Error('Decorating class property failed. Please ensure that transform-class-properties is enabled.');
}

function decorator(target, name, descriptor) {
  // somehow get object when it will be created

  return {
    configurable: true,
    enumerable: true,
    get: function get() {
      // ...
    },
    set: function set(value) {
      // ...
    }
  };
}

var MyClass = (_class = function MyClass() {
  _classCallCheck(this, MyClass);

  _initDefineProp(this, "property", _descriptor, this);
}, (_descriptor = _applyDecoratedDescriptor(_class.prototype, "property", [decorator], {
  enumerable: true,
  initializer: function initializer() {
    return 0;
  }
})), _class);

因此,如果您使用initializer字段返回描述符,则_initDefineProp将使用创建的对象调用它。问题是setter,在这种情况下将会错过getter。

有其他方式吗?请记住,我只能访问装饰器(不是类)。

0 个答案:

没有答案