Javascript 生成一个函数,该函数接受一个对象、路径和值,并返回一个新对象,该对象的值位于path

Javascript 生成一个函数,该函数接受一个对象、路径和值,并返回一个新对象,该对象的值位于path,javascript,object,Javascript,Object,注意:Object.assign将不起作用,因为它只生成浅拷贝 查看Ramda.js的源代码 我希望编写一个简单的函数,它将获取一个对象、一条路径和一个值,并返回一个新对象。理想情况下,新副本应尽可能有效 假设我有一个任意的对象,它可能是 const obj = { a: { b: { c: 1 } } e: 4 } 函数生成的结果示例 const obj2 = func(obj,['a','b','c'],99) console.log(obj

注意:Object.assign将不起作用,因为它只生成浅拷贝

查看Ramda.js的源代码

我希望编写一个简单的函数,它将获取一个对象、一条路径和一个值,并返回一个新对象。理想情况下,新副本应尽可能有效

假设我有一个任意的对象,它可能是

const obj = {
  a: {
    b: {
       c: 1
    }
  }
  e: 4
}
函数生成的结果示例

const obj2 = func(obj,['a','b','c'],99)

console.log(obj2)
// {
//  a: {
//    b: {
//       c: 99
//    }
//  }
//  e: 4
//}

console.log(obj)
// {
//  a: {
//    b: {
//       c: 1
//    }
//  }
//  e: 4
//}
理想的解决方案是高效地创建一个新对象,如下所示:


因此,如果
obj2.e=5
,则
obj.e===5
,因为只有
func
创建了正在修改的分支的副本,但保留了所有其他引用。

可以使用
reduce()
方法执行此操作

const obj={“a”:{“b”:{“c”:1}}
函数func(o,arr,val){
返回arr.reduce(函数(r,e,i){
返回arr[i+1]?(r[e]| |{}):r[e]=val
},o),o
}
const result=func(obj,['a','b','c'],99)

console.log(result)
调整@NenadVracar answer以处理缺少现有属性的边缘情况并创建新对象:

您可以首先克隆对象,然后根据需要使用reduce分解数组以构建路径

function func(o, arr, val) {
    var copyObj = JSON.parse(JSON.stringify(o));
    //OR
    //var copyObj = Object.assign({},o);
    return arr.reduce(function (r, e, i) {
        return arr[i + 1] ? (r[e] || (r[e] = {})) : r[e] = val
    }, copyObj), copyObj
}
我的测试用例:

func({},['b','c'],4)  // {"b":{"c":4}}
func({a:1},['b','c'],4)  // {"a":1,"b":{"c":4}}
func({a:1,b:{d:5}},['b','c'],4)  //{"a":1,"b":{"d":5,"c":4}}
func({a:1,b:{d:5,c:10}},['b','c'],4) //{"a":1,"b":{"d":5,"c":4}}

请注意,该函数返回的是相同的修改对象,而不是新对象。很抱歉,这不提供原始对象的新副本。您正在将相同的对象传递到reduce中,而reduce进入了
func
,并且变异发生在相同的对象上。@nenadvrac喜欢使用逗号运算符。我花了一段时间才弄明白这是怎么回事@Babak,您可以使用
对象。分配
从给定对象创建新对象理想情况下,解决方案将通过创建一个新对象,其中所有节点都引用原始对象,除了发生突变的地方,参考视频@Babak已使用
对象进行编辑。分配
,或者,
JSON.parse
JSON.stringify
的组合。这些方法中的任何一种都应该保持不变性。希望有帮助!祝你好运嘿,谢谢你的回答,我们在讨论的早期讨论过这个问题,但是效率很低。@Babak我明白了。这也适用于Object.assign。祝你好运希望您能找到您正在查找的内容补充说明,JSON.parse/JSON.stringify将说明句柄
Date
和值
未定义的字段