1

What I am trying to achieve:

var obj = new Dynamic({data:"something",data2:"something else"},function(val){
  console.log('"'+val+'"');
});

console.log(obj.data,obj.data2);
obj.data = "this thing here";
console.log(obj.data,obj.data2);

Console output

"something" "something else"
"this thing here"
"something" "something else"

My current console output

"something else" "something else"
"this thing here"
"this thing here" "this thing here"

My Dynamic method looks something like this:

function Dynamic(obj,method){
  var ret;
  var Update = method;
  if(obj instanceof Object){
    ret = {};
    for(var a in obj){
      Object.defineProperty(ret,a,{
        set: function(v){
          inner = v;
          Update.call(this,inner);
        },
        get: function(){
          return inner;
        }
      });
      ret[a] = (obj[a] instanceof Array||obj[a] instanceof Object)?Dynamic(obj[a],Update):obj[a];
    }
  }
  return ret;
}

The issue with this is, every property references inner, not their own version of inner

I have tried

Object.defineProperty(ret,a,{
//set: {dadedadeda}
//get: {dadedadeda}
value:obj[a]});

But this doesn't work due to this issue with get, set, and value which is a humongous oversight in my opinion (what if we DO want a value but also want to intercept the calls?)

I have also tried

Object.defineProperty(ret,a,{
//set: {dadedadeda}
//get: {return this.inner;}
inner:obj[a]});

But it seems that is something that just doesn't happen, and this refers to the whole object anyway, th

Community
  • 1
  • 1
Isaac
  • 11,409
  • 5
  • 33
  • 45

1 Answers1

0

As I was mulling over this question, I actually found my answer: JavaScript Closures (who would've thought)

My full code looks something like this

function Observable(obj, method) {
  function DefineDescriptor(object, key, method, value) {
    var inner = value; // this is the private value of our property
    var descriptor = {
      set: function(v) {
        inner = (v instanceof Object) ? Observable(v, method) : v; // every object added from this point will invoke the method defined
        method.call(this, key, v);
      },
      get: function() {
        return inner;
      }
    };
    Object.defineProperty(object, key, descriptor);
  }
  var ret;
  if (obj instanceof Object) {
    ret = {};
    for (var a in obj) {
      DefineDescriptor(ret, a, method, (obj[a] instanceof Object) ? Observable(obj[a], method) : obj[a]);
    }
  }
  return ret;
}
document.addEventListener("DOMContentLoaded", function(loadEvt) {
  var B = Observable({
    key: "value",
    nested: {
      key: 123,
      str: "hey"
    }
  }, function(key, val) {
    console.log(this, key, this[key], val);
  });
});
Isaac
  • 11,409
  • 5
  • 33
  • 45