2011-01-21 50 views
1

我有這個問題: 我做了一個「通用」的對象與JSON模型的威脅。 我需要通過引用傳遞此模型的屬性,他的'字符串名稱'。 問題是,該屬性是一個值類型不是對象類型,所以我失去了參考和更改將不會傳播。javascript:如何通過'屬性參考'工作

例子:

function Manager(json){this.JsonModel = json;} 
Manager.prototype.Increment = function(propertyName){ 
    this.JsonModel[propertyName]++; 
} 

var manager = new Manager({"a" : 5}); 
alert(manager.Increment("a")); 

ok了對這種情況很好,但什麼工作:?

var manager = new Manager({"a" : {"a1" : 5 }}); 
alert(manager.Increment("a.a1")); 

我該如何做到更好?

Tnx很多。

+1

只是爲了清楚起見:在這裏沒有JSON,JSON只是一個對象的字符串表示;你在這裏處理普通的JavaScript對象,用對象文字符號(≠[JSON](http://json.org))編寫。 – 2011-01-21 13:54:21

+0

Tnx Marcel Korpel:我的錯誤:你是對的! – PadovaBoy 2011-01-21 15:25:59

回答

1

這是我的解決方案:

用途:

警報(CommonUt.GetValueProperty({「馬姆mal「:{」Dog「:{」Value「:5}}},」Mammal.Dog.Value「)); ({「Mammal」:{「Dog」:{「Value」:5}}},「Mammal.Dog.Value」,6);

變種CommonUt = {

/*** 
* Check if the propertyName is present in obj. 
* PropertyName can be a string with 'dot' separator for deepest property 
* Ex: ContainProperty(json, "Mammal.Dog"); 
* @param obj The object where search the property 
* @param propertyName {string} the name of the property 
*/ 
ContainProperty : function(obj, propertyName) { 
    if (!IsNotNullObject(obj)) { 
     return false 
    } 
    if (!IsNotEmptyString(propertyName)) { 
     throw new Error("I cannot check for an empty property name."); 
    } 
    if (propertyName.indexOf('.') === -1) { 
     return (propertyName in obj); 
    } 
    var refObj = obj; 
    var founded = true; 
    $.each(propertyName.split('.'), function(i, item) { 
     if (!(item in refObj)) { 
      founded = false; 
      return false; 
     } 
     refObj = refObj[item]; 
    }); 
    return founded; 
}, 

/*** 
* Get the value of a property (or sub-property) 
* WARN: if the value of the property is 'value-type' any changes will not be propagated! 
* @param obj {object} 
* @param propertyName {string} Property name. For 'deep' property split by dots: Mammal.Dog 
*/ 
GetValueProperty : function(obj, propertyName) { 
    if (!CommonUt.ContainProperty(obj, propertyName)) { 
     throw new Error("I cannot retrieve the property reference if the property doesen't exists!"); 
    } 
    if (propertyName.indexOf('.') === -1) { 
     return obj[propertyName]; 
    } 
    var refObj = obj; 
    $.each(propertyName.split('.'), function(i, item) { 
     refObj = refObj[item]; 
    }); 
    return refObj; 
}, 

/*** 
* To threat with value properties, use this 
* @param obj 
* @param propertyName 
* @param value 
*/ 
SetValueProperty : function(obj, propertyName, value) { 
    if (!CommonUt.ContainProperty(obj, propertyName)) { 
     throw new Error("I cannot retrieve the property reference if the property doesen't exists!"); 
    } 
    if (propertyName.indexOf('.') === -1) { 
     obj[propertyName] = value; 
     return; 
    } 
    var refObj = obj; 
    var slices = propertyName.split('.'); 
    for (var i = 0; i < (slices.length - 1); i++) { 
     refObj = refObj[slices[i]]; 
    } 
    refObj[slices[slices.length-1]] = value; 
} 

};

1

這是「邪惡」的解決方案,但它的工作原理:)

function A(json) { 
    this.Data = json; 
} 

A.prototype.inc = function(prop) { 
    //OMG, It's eval!!! NOOO 
    eval("this.Data." + prop + "++"); 
} 

var p = new A({a : { c : 5 }, b: 2}); 

p.inc("b"); 
alert(p.Data.b); 
p.inc("a.c"); 
alert(p.Data.a.c); 
+0

ehhehe沒有邪惡tnx;)這是我試圖避免的事情:P(tnx的建議) – PadovaBoy 2011-01-21 11:17:13

1

OK,這是不那麼邪惡的解決方案,它也能工作,至少對你有這裏的情景......

function A(json) 
{ 
    this.Data = json; 
} 

A.prototype.inc = function(prop) 
{ 
    var d = this.Data; 

    var s = prop.split("."); 

    for (var i=0; i < s.length - 1; i++) 
    { 
     d = d[s[i]]; 
    } 

    d[s[i]]++; 
} 

    var p = new A({ a : { b : { c : 5 }}}); 

p.inc("a.b.c"); 

alert(p.Data.a.b.c);