当使用R.set或R.merge时,ramda.js是否会创建原始对象的深层克隆?

时间:2017-03-12 03:50:25

标签: ramda.js

当使用R.set(lens,newValue,object)或R.merge(object,newObject)时,有没有人知道ramda.js是否创建了原始对象的深层克隆?

1 个答案:

答案 0 :(得分:2)

在构造具有R.mergeR.set等功能的新对象时,Ramda将重用对象值并通过引用进行复制,而不是不必要地克隆它们。这是基于这样的假设,即所使用的数据类型将始终以不可变的方式使用。

下面的示例应说明给予mergeset时对象内部值的不同。

// 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中以不可变方式运行的函数。