Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript and memoized getters

This article describe getters. It has a section " Smart / self-overwriting / lazy getters" And it's unclear for me, are getters 'memoized' by default or should I implement this feature by myself

e.g.

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

or can I just write:

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

to have the same result?

like image 979
kharandziuk Avatar asked Oct 19 '17 14:10

kharandziuk


1 Answers

The most interesting bit of that article was Smart / self-overwriting / lazy getters, which offers this technique:


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

With this your Foo objects don't go through the hassle of creating their boo properties until you ask for it. Then it's created once and further requests for it simply return the same object. This makes sense if new Boo() is in someway resource-intensive to create and reasonably often is not needed.

Theoretically, you could extend this to allow you to delete the current version and recreate it on next access. But that's a lot more code, and is probably a fairly rare need.

Update

A comment from vrugtehagel correctly pointed out that the above technique, while fine for plain objects, does not work for classes.

Here's a variant which does work:

class Boo {
  static counter = 0
  constructor () {
    this.x = ++Boo.counter
    console .log (`creating Boo(${this.x})`)
  }
}

class Foo {
  get boo () {
    Object .defineProperty (
      this, 
      "boo", 
      { value: new Boo(), writable: false}
    )
    return this .boo;
  }
}

const f = new Foo()

console .log (f.boo) 
console .log (f.boo) // no 'creating Boo' log, Boo constructor only created once
like image 197
Scott Sauyet Avatar answered Oct 18 '22 21:10

Scott Sauyet