在JavaScript中不可变地更新对象的某些属性的最佳方法是什么?

时间:2017-07-14 02:38:36

标签: javascript functional-programming immutability

假设我们有一个像这样的对象:

func (a *A) aSelf() *A {
    return a
}

type myinterface interface {
    SetName(string)
    SetAddress(string)
    aSelf() *A
}

func run() *A {
    // iterate over a slice of myinterface
    for _, s := range []myinterface{
        &B{}, &C{}, &D{},
    } {
        s.SetName("Bob")
        s.SetAddress("Maine")
        // do some other stuff that gets very verbose w/out a slice...
        return s.aSelf()
    }
    return nil
}

现在,如果const obj = { foo: { a: { type: 'foo', baz: 1 }, b: { type: 'bar', baz: 2 }, c: { type: 'foo', baz: 3 } } } 中的baz属性为5,我想将所有属性“type更新为foo。我想以不可变的方式修改它,这意味着它不会修改原始对象但返回一个新对象。

3 个答案:

答案 0 :(得分:1)

我通常写Object.create()用于浅拷贝,但是深拷贝(嵌套对象)用JSON.parse(JSON.stringify(nestedObject))

const obj = {
  foo: {
    a: { type: 'foo', baz: 1 },
    b: { type: 'bar', baz: 2 },
    c: { type: 'foo', baz: 3 }
  }
}
var temp = JSON.parse(JSON.stringify(obj))

for(var i in temp.foo) {
  if(temp.foo[i].type == "foo") {
    temp.foo[i].baz = 5;
  }
}
console.log(temp);
console.log(obj);

答案 1 :(得分:0)

Object.assign非常适合docs

  

Object.assign()方法用于将所有可枚举的自有属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

你可以像这样使用它:

Object.assign(
    {},
    obj,
    {
        foo: {
            a: {
                baz: obj.foo.a.type === 'foo' ? 5 : obj.foo.a
            }
        }
    }
);

答案 2 :(得分:-1)

您可以使用Object.entries()Array.prototype.map(),展开元素,计算属性,Object.assign()

const obj = {
  foo: {
    a: { type: 'foo', baz: 1 },
    b: { type: 'bar', baz: 2 },
    c: { type: 'foo', baz: 3 }
  }
}

let key = Object.keys(obj).pop();

let res = {[key]: Object.assign({},
          ...Object.entries(obj[key])
          .map(([prop, {type,baz}]) => 
            ({[prop]: {type,baz:type === "foo" ? 5 : baz}})
          ))};
  
console.log(res, obj);