【问题标题】:javascript: how to work by 'property reference'javascript:如何通过“属性参考”工作
【发布时间】:2011-06-13 01:53:49
【问题描述】:

我有这个问题: 我用 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 很多。

【问题讨论】:

  • 为了清楚起见:这里没有JSON,JSON只是一个对象的字符串表示;你在这里处理的是纯 JavaScript 对象,用对象字面量表示法 (≠ JSON)。
  • Tnx Marcel Korpel:我的错误:你是对的!

标签: javascript generics properties pass-by-reference


【解决方案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);

【讨论】:

  • ehhehe no evil tnx ;) 这是我尽量避免的事情:P(tnx 建议)
【解决方案2】:

好的,这是一个不那么邪恶的解决方案,它也有效,至少对于你在这里的场景......

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);

【讨论】:

  • !我们同步了!我刚刚完成实施类似的解决方案!现在我发布它! Tnx 很多。 (ps:这不是魔鬼,但我也不喜欢 :(
【解决方案3】:

这是我的解决方案:

用法:

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;
}

};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2019-09-02
    • 2017-12-25
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    相关资源
    最近更新 更多