6

是否可以在提案的当前迭代中定义一个将在实例级别公开的装饰器

例如

function once(target, name, descriptor) {
  let {get} = descriptor;
  var called = false, result;
  if (typeof get === "function") {
    descriptor.get = function() {
      console.log(called);
      if (!called) {
          result = get.apply(this, arguments);
          called = true;
      }
      return result;
   }
  }
  return descriptor;
};

class X {
    @once
    get y() {
      return Math.random();
    }
}

var x1 = new X;
var x2 = new X;


// Should be false
console.log(x1.y !== x2.y)

我想要类似于做的行为

class X2 {
  constructor() {
     // Set descriptor manually for this instance
    let descriptor = Object.getOwnPropertyDescriptor(X2.prototype, 'y');
    let d = Object.assign({}, descriptor);
    once(X, "y", d);
    Object.defineProperty(this, 'y', d);
  }
  get y() {
    return Math.random();
  }
}

Babel REPL 示例

4

1 回答 1

5

装饰器只在定义类时运行一次,但这并不意味着定义时逻辑不能设置函数来为每个实例做一些事情。在这种情况下,您可以通过在原型级 getter 中定义特定于实例的属性来记忆值;

function once(target, name, descriptor) {
  let {get, writable, enumerable} = descriptor;
  if (typeof get === "function") {
    descriptor.get = function() {
      const value = get.apply(this, arguments);
      Object.defineProperty(this, name, {
        value,
        writable,
        enumerable
      });

      return value;
   }
  }
  return descriptor;
};
于 2015-05-14T05:38:31.227 回答