2012-10-17 4 views
0

J'ai essayé toute la journée pour trouver un moyen de faire ce travail. Ça m'embête vraiment. J'ai lu des tas d'articles sur OOP et même si je sais que mon code n'est pas parfait, je n'arrive pas à contourner le problème initial que j'ai décrit dans mon code ci-dessous.JavaScript OOP setter getter dynamique - Qu'est-ce que je fais mal

Tous les travaux de code à l'exception de la dynamique getter/setter - Si vous lisez mes commentaires dans le code ou exécutez le code, vous pouvez facilement voir pourquoi.

J'ai le sentiment que ce que j'essaie de faire ne peut être fait. Quelqu'un peut-il me dire où je vais mal, ou si cela ne peut pas être fait comme je l'ai proposé.

  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 

Répondre

0

J'ai trouvé la solution. La réponse consistait à utiliser une enceinte et à piéger l'index de boucle (i).

Cela a été magnifiquement expliqué dans l'article de

Explaining javascript Scope and closures

L'altération de mon code est la suivante et fonctionne un régal!

  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;