【问题标题】:Dynamic observable object动态可观察对象
【发布时间】:2015-10-23 18:43:47
【问题描述】:

我想要达到的目标:

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);

控制台输出

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

我当前的控制台输出

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

我的Dynamic 方法如下所示:

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;
}

问题在于,每个属性都引用inner,而不是它们自己的内部版本

我试过了

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

但这不起作用,因为 this issue with get, set, and value 在我看来这是一个巨大的疏忽(如果我们确实想要一个值但又想拦截调用怎么办?)

我也试过

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

但这似乎是不会发生的事情,this 无论如何都是指整个对象,th

【问题讨论】:

    标签: javascript object getter-setter object-property


    【解决方案1】:

    当我在思考这个问题时,我实际上找到了答案:JavaScript Closures(谁会想到)

    我的完整代码看起来像这样

    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);
      });
    });

    【讨论】:

      猜你喜欢
      • 2015-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 2011-06-17
      • 2019-01-30
      相关资源
      最近更新 更多