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

Does ramda.js create a deep clone of the original object when using R.set or R.merge?

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

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

下面的例子应该说明当给予 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 中那些以不可变方式运行的函数。