I need a lazy loading variables in JavaScript. Taking inspiration from Any way to define getters for lazy variables in Javascript arrays? and from Self-references in object literal declarations I have tried this solution
var console = {
  log: function(s) {
    s = s.replace(/\\n/, '<br/>');
    document.getElementById("console").innerHTML += s + "<br/>"
  }
}
function MyClass() {
  this.LazyProperty = {
    _loaded: false,
    _autoload: function() {
      console.log("MyClassLazyProperty-1 " + JSON.stringify(this));
      if (this._loaded) {
        console.log("MyClass.LazyProperty-2 " + JSON.stringify(this));
        return this;
      } else {
        setTimeout(function(self) {
          self._loaded = true;
          self.profile = {
            displayName: "Loreto Parisi"
          };
          console.log("MyClass.LazyProperty-3 " + JSON.stringify(self));
          self._autoload();
        }, 300, this);
      }
    }
  }._autoload()
  this.User = {
    username: "loretoparisi",
    _autoload: function() {
      console.log("MyClass.User-1" + JSON.stringify(this));
      return this;
    }
  }._autoload()
}
var c = new MyClass();
console.log("c.User\n" + JSON.stringify(c.User));
console.log("c.LazyProperty\n" + JSON.stringify(c.LazyProperty));<div id="console" />Code Explanation
Supposed that I want to populate the lazy property by result of a asynchronous lookup (like a rest request), I need to keep a status of the loading at first lookup. The _autoload function makes the async lookup and sets the response properties, so I would expect to have the object filled here:
c.LazyProperty
while the result is undefined. Why?
EDIT
I have found out that something happens when calling the setTimeout, so that the reference to this is lost, so I have added a defer function that shall keep it:
_defer : function() { this._autoload(); return this },
At that point the lazy loader will work properly:
var console = {
  log: function(s) {
    s = s.replace(/\\n/, '<br/>');
    document.getElementById("console").innerHTML += s + "<br/>"
  }
}
function MyClass() {
  this.LazyProperty = {
_loaded: false,
_defer : function() { if(!this._loaded) this._autoload(); return this },
_autoload: function() {
  console.log("MyClassLazyProperty-1 " + JSON.stringify(this));
  setTimeout(function(self) {
      self._loaded = true;
      self.profile = {
        displayName: "Loreto Parisi"
      };
      console.log("MyClass.LazyProperty-3 " + JSON.stringify(self));
    }, 300, this);
}
  }. _defer()
  this.User = {
username: "loretoparisi",
_autoload: function() {
  console.log("MyClass.User-1" + JSON.stringify(this));
  return this;
}
  }._autoload()
}
var c = new MyClass();
console.log("c.User\n" + JSON.stringify(c.User));
console.log("BEFORE: c.LazyProperty\n" + JSON.stringify(c.LazyProperty));
setTimeout( function() {
   console.log("AFTER: c.LazyProperty\n" + JSON.stringify(c.LazyProperty));
},1000);<div id="console" />Given this solution, in the first execution I don't get why the property is undefined after it has been assigned.
 
    