2012-10-17 35 views
0

我一直試圖找到一種方法來完成這項工作。這真的讓我煩惱。我已閱讀了大量有關OOP的文章,儘管我知道我的代碼並不完美,但似乎無法解決我在下面的代碼中列出的最初問題。JavaScript OOP動態getter setter - 我做錯了什麼

所有代碼的工作,除了動態getter/setter - 如果你在代碼讀我的意見或運行代碼,你可以很容易地看到爲什麼。

我有一種感覺,我試圖做的事情無法完成。有人可以告訴我我要去哪裏錯,或者如果我不能按我提出的方式完成。

  var ext = { 
     db: { 
      string: function(def){ 
       def=def || {}; 
       def.type = "string"; 
       return def; 
      }, 
      autoId: function(def){ 
       def=def || {}; 
       def.defaultvalue = function(){ 
        return Math.uuid(def.length, def.radix) 
        return def; 
       } 
      } 
     }, 
    } 
    /* 
    * @ext.base:  base class I can build out with common methods 
    *     
    */ 
    ext.base = function(){ 
     /* 
     * place holder for the raw object data - 
     * 
     * {a:"martin webb",b:"is struggling with this" 
     * 
     */ 
     this._rawdata={}; // this can later be strigified for storage; 

    }; 
    ext.base.prototype ={ 
     init:function(o){ 
      // pass in rawdata; 
      this.load(o); 
     }, 
     put:function(){ 
      //code removed 
     }, 
     load: function(rawdata){ 
      this._rawdata=rawdata || {}; 
     } 

    } 
    /* 
    * @ext.kind:  builds a new object we can use to make entities from our kind 
    *     martin=new people(); 
    * 
    */ 
    ext.db.kind=function(o){ 
     this._kind=function(o){this.init(o);} //this will pass any passed in object in the base class at init; 
     this._kind.prototype = ext.base.prototype; 

     var self=this; 

     var prop,i=97; //ascii for "a"; 
     for (prop in o){ 
      if (o.hasOwnProperty(prop)) { 
       /* 
       * This is like a dynamic getter setter, we are adding it to the prototype; 
       * 
       * if you run the code when the function below is called 
       * value="martin webb" I need the var i to equal 97, and prop to = "name" 
       * in the function. I need a way to pass in and conserver these dynamic values 
       */ 
       this._kind.prototype[prop] = 
        function(value){ 
         if (value) { 
          self.rawdata[i] = value; //ERROR i=99! 
         } 
         return self.rawdata[i] ; //get the correct data using the key 
        }; 

        i++; 
       } 

     } 
     return this._kind; // return our new object so we can use it like var martin=new people(); 
    } 
    debugger; 
    //lets make a new kind; 
    var people={}; 
    people.name=ext.db.string(); 
    people.info=ext.db.string(); 
    people = new ext.db.kind(people); 
    //and now make some entities usinhg it; 
    var martin=new people(); 


    //THE CODE WILL GO WRONG HERE, THE SETTER WILL NOT WORK (SEE ABOVE) 

    martin.name("martin webb") 
    martin.info("is struggling with this code") 

    var mike = new people({ 
     a: "mike", 
     b: "has the solution" 
    }); 
    console.log(mike.name()) //--> mike 

回答

0

我找到了解決方案。答案是使用外殼並捕獲循環索引(i)。

這是漂亮的文章中通過

Explaining javascript Scope and closures

的改動,我的代碼如下,工程請客解釋!

  var prop, i = 97; //ascii for "a"; 
      //loop each property and make our own get/setter that works 
      //off our underlying compressed rawdata; 
      for (prop in o) { 
       if (o.hasOwnProperty(prop)) { 
        /* 
        * this is the trick 
        * use an enclosure and pass our loop index in the bottom 
        * with a self calling function, this locks the value of i; 
        */ 
        this._kind.prototype[prop] = function(k){ 
         return function(value){ 
          var key=String.fromCharCode(k); 
          //if we have a value passed in set it! 
          if (value){ 
           this._rawdata[key]=value; 
          } 
          //always return our value; 
          return this._rawdata[key]; 
         }; 
         }(i); //here we call our function and lock index i; 

        i++; 
       }//end loop;