代码之家  ›  专栏  ›  技术社区  ›  Bluefire

如何根据对象在对象中的位置修改对象属性

  •  1
  • Bluefire  · 技术社区  · 8 年前

    obj ,我可以使用以下内容修改其属性 obj.a.b.c = "new value" 。但是,我希望能够以编程方式完成此操作,以数组的形式显示属性的位置。如何生成如下所示的函数:

    modifyProperty(obj, ["a", "b", "c"], "new value");

    并且相当于

    obj.a.b.c = "new value";

    ?

    3 回复  |  直到 8 年前
        1
  •  2
  •   Nina Scholz    8 年前

    你可以用 Array#reduce 对于它,如果没有可用的对象,则使用默认对象。

    function modifyProperty(object, path, value) {
        var last = path.pop();
        path.reduce(function (r, a) {
            if (!(a in r)) {
                r[a] = {};
            }
            return r[a];
        }, object)[last] = value;
    }
    
    var object = {};
    modifyProperty(object, ["a", "b", "c"], "new value");
    console.log(object);
        2
  •  1
  •   jfriend00    8 年前

    你可以这样做:

    function modifyProperty(obj, props, val) {
        var propName = props.pop();
        var o = props.reduce(function(obj, p) {
            return obj[p];
        }, obj);
        o[propName] = val;
    }
    
    var obj = {
       a: {b: {c: "old value"}}
    }
    
    modifyProperty(obj, ["a", "b", "c"], "new value");
    
    console.log(obj);
        3
  •  0
  •   Redu    8 年前

    为了动态设置对象值,我有一个名为 Object.prototype.setNestedValue() 这将采用一个指定数组属性的项目数组,最后一个是值。例如

    Object.prototype.setNestedValue = function(...a) {
      a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
                                                                           : (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]),
                                                                             this[a[0]].setNestedValue(...a.slice(1)))
                   : this[a[0]] = a[1];
      return this;
    };
    
    var obj = {}.setNestedValue("a","b","c",100);
    console.log(JSON.stringify(obj,null,2));

    如果使用整数代替字符串参数,则会得到一个数组,例如

    Object.prototype.setNestedValue = function(...a) {
          a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
                                                                               : (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]),
                                                                                 this[a[0]].setNestedValue(...a.slice(1)))
                       : this[a[0]] = a[1];
          return this;
        };
    
        var obj = {}.setNestedValue("a",2 ,3,100);
        console.log(JSON.stringify(obj,null,2));