我有这个问题: 我用json模型制作了一个威胁的“通用”对象。 我需要通过他的'字符串名称'来引用该模型的属性。 问题是属性是值类型而不是对象类型,因此我将丢失引用,并且不会传播更改。
示例:
function Manager(json){this.JsonModel = json;}
Manager.prototype.Increment = function(propertyName){
this.JsonModel[propertyName]++;
}
var manager = new Manager({"a" : 5});
alert(manager.Increment("a"));
好吧它运作良好但是这种情况怎么样??
var manager = new Manager({"a" : {"a1" : 5 }});
alert(manager.Increment("a.a1"));
我怎么能以更好的方式做到这一点?
Tnx对所有人都很重要。
答案 0 :(得分: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);
答案 1 :(得分:1)
好的,这不是那么邪恶的解决方案,它也有效,至少对于你在这里的场景......
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);
答案 2 :(得分:1)
这是我的解决方案:
用途:
alert(CommonUt.GetValueProperty({“Mammal”:{“Dog”:{“Value”:5}}},“Mammal.Dog.Value”)); CommonUt.SetValueProperty({“Mammal”:{“Dog”:{“Value”:5}}},“Mammal.Dog.Value”,6);
var 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;
}
};