javascript和memoized getters

时间:2017-10-19 14:32:37

标签: javascript ecmascript-6 getter-setter getter

question you link to。它有一个部分" 聪明/自我覆盖/懒惰的吸气者" 对我来说,不清楚的是吸气剂是否已经被记忆化了?'默认情况下或我应该自己实现此功能

e.g。

class Foo() {
  get boo() {
    this._boo = this._boo || new Boo(); 
    return this._boo;  
  }
}

或者我可以写一下:

class Foo() {
  get boo() {
    return new Boo();  
  }
}

得到相同的结果?

4 个答案:

答案 0 :(得分:3)

您可以随意添加便笺,例如

未记录,

class NonMemoized {
  constructor(prefix) {
    this.prefix = prefix;
  }

  get myFunc() {
    return this.prefix + Math.random().toString();
  }
}

let nonMemoized = new NonMemoized('new number each time ');
console.log(nonMemoized.myFunc);
console.log(nonMemoized.myFunc);

已记忆,非常适合当您想一次创建一个对象并总是返回相同的对象时(但又不想​​在构造函数中创建,因为可能不需要一直都这样或其他原因)

class MemoizedManually {
  constructor(prefix) {
    this.prefix = prefix;
  }

  get myFunc() {
    return this._myFunc_ = this._myFunc_ || this.prefix + Math.random().toString();
  }
}

let memoizedManually = new MemoizedManually('same number ');
console.log(memoizedManually.myFunc);
console.log(memoizedManually.myFunc);

最后,如果您有一堆函数要记住,但不想在每个函数中重复使用this.x = this.x || something computation(您不应该重复,因为这并不是{{ 1}}来记住自己:

myFunc

关于吸气剂的妙处在于它们不接受参数,因此您不必担心class Memoized { constructor(prefix) { this.prefix = prefix; } get myFunc() { return this.prefix + Math.random().toString(); } } const memoizeGetter = (clazz, functionName) => { let func = Object.getOwnPropertyDescriptor(clazz.prototype, functionName); let cacheKey = `_${functionName}-cache_`; Object.defineProperty(clazz.prototype, functionName, { get: function () { return this[cacheKey] = this[cacheKey] || func.get.call(this); } }); }; memoizeGetter(Memoized, 'myFunc'); let memoized = new Memoized('also same number '); console.log(memoized.myFunc); console.log(memoized.myFunc); ,但不必担心绑定...args

答案 1 :(得分:2)

不,JavaScript中的memoized getter没有语言级支持。在第二个示例中,每次访问boo时都会创建一个新对象。

答案 2 :(得分:2)

该文章中最有趣的一点是Smart / self-overwriting / lazy getters,它提供了这种技术:

class Foo {
  get boo() {
    delete this.boo;
    return this.boo = new Boo();
  }
}

有了这个,你的Foo对象就不会经历创建boo属性的麻烦,直到你要求它为止。然后它创建了一次,对它的进一步请求只返回相同的对象。如果new Boo()在某种程度上是资源密集型的,那么这是有道理的,而且通常不需要。

理论上,您可以对此进行扩展,以允许您删除当前版本并在下次访问时重新创建它。但这需要更多代码,而且可能是一种相当罕见的需求。

答案 3 :(得分:0)

考虑这段代码:

class Person {
    static get SHORT() { return 0; }//rvalue
}

class Person {}
Person.SHORT = 0;//lvalue

虽然两者都返回相同的结果,但后者实际上更快(因为它避免了函数调用开销);虽然js引擎可以进行优化,使一个优先于另一个。