2016-04-13 17 views
2

Böyle bir nesne örneği var ki bir olsun/bazı basit şifrelemek sağlamak için bu nesne için ayarlanmış/özelliğini şifresini:set olsun Object.defineProperty dönüş yanlış değer

hookSetGet: function (someObject) { 
    for (var key in someObject) { 
     cc.log("key: " + key); 

     // store the origin value before Object.defineProperty 
     var pureValue = someObject[key]; 

     // add a property to store the encrypted value 
     var hiddenValueKey = "__" + key; 
     someObject[hiddenValueKey] = undefined; 

     Object.defineProperty (
      someObject, 
      key, 
      { 
       set: function (val) { 
        // simulate encrypt 
        this.hiddenValueKey = val + 1; 
        cc.log("hooked set: " + val + " - " + this.hiddenValueKey); 
       }, 
       get: function() { 
        cc.log("hooked get: " + this.hiddenValueKey + " - " + (this.hiddenValueKey - 1)); 
        // simulate decrypt 
        return this.hiddenValueKey - 1; 
       } 
      } 
     ); 

     // trigger set to encrypt 
     someObject[key] = pureValue; 
    } 
} 

ama böyle fonksiyonu test ederken:

var objectA = {"a": 1, "b": 2, "c" : 3}; 
this.hookSetGet(objectA); 

cc.log(objectA.a); 
cc.log(objectA.b); 
cc.log(objectA.c); 

ben sonuç alamadım istediğim:

key: a 
hooked set: 1 - 2 
key: b 
hooked set: 2 - 3 
key: c 
hooked set: 3 - 4 

hooked get: 4 - 3 
3 
hooked get: 4 - 3 
3 
hooked get: 4 - 3 
3 

Ben

objectA.a 

çağrı bile gibi görünüyor ben

objectA.c 

değerini alacak Sorun oldukça basit görünüyor ama ben sadece inc olamaz neyin yanlış olduğunu araştır.

Herhangi bir öneri takdir edilecektir

, teşekkürler :)

GÜNCELLEME:

Ben değişiklik olmaksızın hookSetGet kodunu aşağıdaki kodu çalıştı:

cc.log(objectA.__a); 
cc.log(objectA.__b); 
cc.log(objectA.__c); 

ve almak:

undefined 
undefined 
undefined 

Daha sonra hookSetGet işlevini değiştirdim:

set: function (val) { 
    // simulate encrypt 
    someObject[hiddenValueKey] = val + 1; 
    cc.log("hooked set: " + val + " - " + someObject[hiddenValueKey]); 
}, 
get: function() { 
    cc.log("hooked get: " + someObject[hiddenValueKey] + " - " + (someObject[hiddenValueKey] - 1)); 
    // simulate decrypt 
    return someObject[hiddenValueKey] - 1; 
} 

Tüm this.hiddenValueKey 'i SomeObject [hiddenValueKey] olarak değiştirdim.

ve çıktısı:

cc.log(objectA.__a); // 2 good 
cc.log(objectA.__b); // 3 good 
cc.log(objectA.__c); // 4 good 

cc.log(objectA.a); // hooked get: 4 - 3 still wrong 
cc.log(objectA.b); // hooked get: 4 - 3 still wrong 
cc.log(objectA.c); // hooked get: 4 - 3 still wrong 
+0

bu akıllıca mı bunun üstesinden numaralandırılırken ise bir nesneyi değiştirmek için? –

+0

@MatthewHerbst: Evet, bu önemli olmamalı, özellikler iki kez yinelenmez. – Bergi

+0

[nokta notasyonu vs parantez notasyonu] 'nın olası kopyası (https://stackoverflow.com/questions/4968406/javascript-property-access-dot-notation-vs-brackets) ve [JavaScript döngüleri iç içe geçirme] (http: // stackoverflow.com/q/750486/1048572) – Bergi

cevap

0

sizin koduyla çeşitli faktörler vardır. Bunlardan bir tanesi, ve hiddenValueKey'un hookGetSet işlevinin kapsamında ayarlanmış olmasıdır. Bu nedenle, bunları her kullandığınızda, döngüdeki son değeri kullanırsınız (3 ve __c). Bunu iki şekilde bu düzeltebilirsiniz: döngü kapsamında key ve hiddenValueKey tanımlamak için let yerine var ait

  • kullanımı, ama bu sadece döngünün kapsamına içini bir kapatma kullanmak ES6
  • yılında
  • çalışır

Diğer bir sorun da, bu amaçla kullandığınız özellikler içinde this.hiddenValueKey, this['hiddenValueKey'] ile aynıdır, this[hiddenValueKey] amaçladığınız gibi. İşte

çalışır kodu (EcmaScript6) 'dir:

hookSetGet : function (someObject) { 
    for (let key in someObject) { 
     cc.log("key: " + key); 

     // store the origin value before Object.defineProperty 
     var pureValue = someObject[key]; 

     // add a property to store the encrypted value 
     let hiddenValueKey = "__" + key; 
     someObject[hiddenValueKey] = undefined; 

     Object.defineProperty(
      someObject, 
      key, { 
      set : function (val) { 
       // simulate encrypt 
       this[hiddenValueKey] = val + 1000; 
       cc.log("hooked set: " + val + " - " + this[hiddenValueKey]); 
      }, 
      get : function() { 
       // simulate decrypt 
       var result = this[hiddenValueKey] - 1000; 
       cc.log("hooked get: " + this[hiddenValueKey] + " - " + result); 
       return result; 
      } 
     }); 

     // trigger set to encrypt 
     someObject[key] = pureValue; 
    } 
} 

ve burada klasik ES5 JavaScript için aynı kodu:

hookSetGet : function (someObject) { 
    for (var k in someObject) { 
     (function() { 
      var key = k; 
      cc.log("key: " + key); 

      // store the origin value before Object.defineProperty 
      var pureValue = someObject[key]; 

      // add a property to store the encrypted value 
      var hiddenValueKey = "__" + key; 
      someObject[hiddenValueKey] = undefined; 

      Object.defineProperty(
       someObject, 
       key, { 
       set : function (val) { 
        // simulate encrypt 
        this[hiddenValueKey] = val + 1000; 
        cc.log("hooked set: " + val + " - " + this[hiddenValueKey]); 
       }, 
       get : function() { 
        // simulate decrypt 
        var result = this[hiddenValueKey] - 1000; 
        cc.log("hooked get: " + this[hiddenValueKey] + " - " + result); 
        return result; 
       } 
      }); 

      // trigger set to encrypt 
      someObject[key] = pureValue; 
     })(); 
    } 
} 
+0

Yardımlarınız için teşekkürler :) Artık her şey gayet güzel çalışıyor :) – supersuraccoon

1

Yani, bu yazmış: this.hiddenValueKey adresinin alıcı ve ayarlayıcı this yılında

Object.defineProperty (
     someObject, 
     key, 
     { 
      set: function (val) { 
       // simulate encrypt 
       this.hiddenValueKey = val + 1; 
       cc.log("hooked set: " + val + " - " + this.hiddenValueKey); 
      }, 
      get: function() { 
       cc.log("hooked get: " + this.hiddenValueKey + " - " + (this.hiddenValueKey - 1)); 
       // simulate decrypt 
       return this.hiddenValueKey - 1; 
      } 
     } 
    ); 

her durumda değil, her bir özellik için objectA Nesne ifade eder . Yani, her özellik için bir değer ayarlamak istediğinizde, objectA.hiddenValueKey'un üzerine yazıyorsunuz demektir. Bu nedenle, get değerini geri döndürdüğünüzde, değerleri yalnızca ayarlanmış olan son değeri elde edersiniz.

hiddenValueKey'u benzersiz olarak ayarlamanıza rağmen, alıcı ve ayarlayıcıda aynı özelliği görürsünüz. Bunun nedeni, this.hiddenValueKey'un this['hiddenValueKey'] yazmayla aynı olmasıdır. this[hiddenValueKey] mu demek istediniz? Bunu yapsanız bile, döngüden çıktıktan sonra her zaman en son anahtar değere sahip olan hiddenValueKey ile bazı kapsam sorunları olabilir.Dediğim gibi, bunu her özellik alıcı ve ayarlayıcı için benzersiz olacaktır böylece hiddenValueKey değişken için bir kapatma oluşturmak gerekebilir,

Object.defineProperty (
     someObject, 
     key, 
     { 
      set: function (val) { 
       // simulate encrypt 
       this[hiddenValueKey] = val + 1; 
       cc.log("hooked set: " + val + " - " + this[hiddenValueKey]); 
      }, 
      get: function() { 
       cc.log("hooked get: " + this[hiddenValueKey] + " - " + (this[hiddenValueKey] - 1)); 
       // simulate decrypt 
       return this[hiddenValueKey] - 1; 
      } 
     } 
    ); 

Ama:

Yani, bu deneyebilirsiniz.

Böyle bir kapatma oluşturabilirsiniz:

(function(hiddenValueKey) { 
    Object.defineProperty (
     someObject, 
     key, 
     { 
      set: function (val) { 
       // simulate encrypt 
       this[hiddenValueKey] = val + 1; 
       cc.log("hooked set: " + val + " - " + this[hiddenValueKey]); 
      }, 
      get: function() { 
       cc.log("hooked get: " + this[hiddenValueKey] + " - " + (this[hiddenValueKey] - 1)); 
       // simulate decrypt 
       return this[hiddenValueKey] - 1; 
      } 
     } 
); 
    }(hiddenValueKey));