当使用R.set(lens,newValue,object)或R.merge(object,newObject)时,有没有人知道ramda.js是否创建了原始对象的深层克隆?
答案 0 :(得分:2)
在构造具有R.merge
和R.set
等功能的新对象时,Ramda将重用对象值并通过引用进行复制,而不是不必要地克隆它们。这是基于这样的假设,即所使用的数据类型将始终以不可变的方式使用。
下面的示例应说明给予merge
或set
时对象内部值的不同。
// merge example
const obj1 = { a1: { b1: { c1: {}, c2: {} }, b2: {} }, a2: {} }
const obj2 = R.merge(obj1, { a2: 3 })
// only `a2` is modified, so the other values are copied by reference
obj1.a2 === obj2.a2 // false
obj1.a1 === obj2.a1 // true
obj1.a1.b1 === obj2.a1.b1 // true
obj1.a1.b1.c1 === obj2.a1.b1.c1 // true
// lens example
const c1Lens = R.lensPath(['a1', 'b1', 'c1'])
const obj3 = R.set(c1Lens, {}, obj1)
// `a1.b1.c1` was modified, so each parent object needs to be recreated as new
obj1.a1 === obj3.a1 // false
obj1.a1.b1 === obj3.a1.b1 // false
obj1.a1.b1.c1 === obj3.a1.b1.c1 // false
// `a2`, `a1.b2`, `a1.b1.c2` were unaffected by the change so they retain the same references
obj1.a2 === obj3.a2 // true
obj1.a1.b2 === obj3.a1.b2 // true
obj1.a1.b1.c2 === obj3.a1.b1.c2 // true
如果必须对共享结构引用的对象进行突变,那么最好在变异之前通过像R.clone
这样的对象来过去,以确保其他对象不受影响。否则,只需尝试坚持使用Ramda中以不可变方式运行的函数。