不可变方法如何在 lodash fp 中工作?

How do immutable methods work in lodash fp?

我想了解 lodash/fp 的不可变方法是如何工作的。

他们是在更改集合之前深度克隆集合,还是在对象的两个版本之间实现某种结构共享?

我试图从“外部”去理解它,但我无法得出明确的结论。

在下面的第一种情况下,改变更新后的集合不会影响原始集合。

但是,在第二种情况下,改变更新后的集合确实会影响原始集合。

var fp = _.noConflict();

var data = { a: { c: {} } };
var updatedData = fp.set(["a", "c", "d"], 5, data);
updatedData.a.c.e = 9;
console.log(updatedData.a.c.e, data.a.c.e);

var data2 = { a: { c: [] } };
var updatedData2 = fp.set(["a", "d"], 5, data2);
updatedData2.a.c[0] = 9;
console.log(updatedData2.a.c[0], data2.a.c[0]);
<script src='https://cdn.jsdelivr.net/g/lodash@4.17(lodash.min.js+lodash.fp.min.js)'></script>

我也在 Lodash github 上发布了问题。

Do they deeply clone a collection before changing it or do they implement kind of a structural sharing between the two versions of the object?

是的,他们使用结构共享。

我们可以在这个例子中看到 c 对象被重用,而不是被克隆。这很有用,因为它的大小可能非常大(在我的例子中,它包含整个 window 对象!)。
您可以想象尝试深度克隆它会浪费资源。

var fp = _.noConflict()
var data, updatedData


data = { a: { c: { window: window } } }
updatedData = fp.set(["a", "d"], 5, data)
console.log(updatedData.a.c === data.a.c)
<script src='https://cdn.jsdelivr.net/g/lodash@4.17(lodash.min.js+lodash.fp.min.js)'></script>

只更改了“父”对象,因此必须克隆它们。不属于突变的叶子不需要改变。

你的例子出错的原因是你结合了不可变和可变代码,这不是一个好主意。如果您更改预期不可变的代码,这些克隆优化显然会出错。